No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

203 líneas
6.1 KiB

  1. package sidh
  2. import (
  3. "errors"
  4. p751 "github.com/cloudflare/p751sidh/p751toolbox"
  5. // . "github.com/cloudflare/p751sidh/internal/utils"
  6. "io"
  7. )
  8. // I keep it bool in order to be able to apply logical NOT
  9. type KeyVariant uint
  10. type PrimeFieldId uint
  11. // Id's correspond to bitlength of the prime field characteristic
  12. // Currently FP_751 is the only one supported by this implementation
  13. const (
  14. FP_503 PrimeFieldId = iota
  15. FP_751
  16. FP_964
  17. maxPrimeFieldId
  18. )
  19. const (
  20. // First 2 bits identify SIDH variant third bit indicates
  21. // wether key is a SIKE variant (set) or SIDH (not set)
  22. // 001 - SIDH: corresponds to 2-torsion group
  23. KeyVariant_SIDH_A KeyVariant = 1 << 0
  24. // 010 - SIDH: corresponds to 3-torsion group
  25. KeyVariant_SIDH_B = 1 << 1
  26. // 110 - SIKE
  27. KeyVariant_SIKE = 1<<2 | KeyVariant_SIDH_B
  28. )
  29. // Base type for public and private key. Used mainly to carry domain
  30. // parameters.
  31. type key struct {
  32. // Domain parameters of the algorithm to be used with a key
  33. params *SidhParams
  34. // Flag indicates wether corresponds to 2-, 3-torsion group or SIKE
  35. keyVariant KeyVariant
  36. }
  37. // Defines operations on public key
  38. type PublicKey struct {
  39. key
  40. affine_xP p751.ExtensionFieldElement
  41. affine_xQ p751.ExtensionFieldElement
  42. affine_xQmP p751.ExtensionFieldElement
  43. }
  44. // Defines operations on private key
  45. type PrivateKey struct {
  46. key
  47. // Secret key
  48. Scalar []byte
  49. // Used only by KEM
  50. S []byte
  51. }
  52. // Accessor to the domain parameters
  53. func (key *key) Params() *SidhParams {
  54. return key.params
  55. }
  56. // Accessor to key variant
  57. func (key *key) Variant() KeyVariant {
  58. return key.keyVariant
  59. }
  60. // NewPrivateKey initializes private key.
  61. // Usage of this function guarantees that the object is correctly initialized.
  62. func NewPrivateKey(id PrimeFieldId, v KeyVariant) *PrivateKey {
  63. prv := &PrivateKey{key: key{params: Params(id), keyVariant: v}}
  64. prv.Scalar = make([]byte, prv.params.SecretKeySize)
  65. if v == KeyVariant_SIKE {
  66. prv.S = make([]byte, prv.params.MsgLen)
  67. }
  68. return prv
  69. }
  70. // NewPublicKey initializes public key.
  71. // Usage of this function guarantees that the object is correctly initialized.
  72. func NewPublicKey(id PrimeFieldId, v KeyVariant) *PublicKey {
  73. return &PublicKey{key: key{params: Params(id), keyVariant: v}}
  74. }
  75. // Import clears content of the public key currently stored in the structure
  76. // and imports key stored in the byte string. Returns error in case byte string
  77. // size is wrong. Doesn't perform any validation.
  78. func (pub *PublicKey) Import(input []byte) error {
  79. if len(input) != pub.Size() {
  80. return errors.New("sidh: input to short")
  81. }
  82. pub.affine_xP.FromBytes(input[0:pub.params.SharedSecretSize])
  83. pub.affine_xQ.FromBytes(input[pub.params.SharedSecretSize : 2*pub.params.SharedSecretSize])
  84. pub.affine_xQmP.FromBytes(input[2*pub.params.SharedSecretSize : 3*pub.params.SharedSecretSize])
  85. return nil
  86. }
  87. // Exports currently stored key. In case structure hasn't been filled with key data
  88. // returned byte string is filled with zeros.
  89. func (pub *PublicKey) Export() []byte {
  90. output := make([]byte, pub.params.PublicKeySize)
  91. pub.affine_xP.ToBytes(output[0:pub.params.SharedSecretSize])
  92. pub.affine_xQ.ToBytes(output[pub.params.SharedSecretSize : 2*pub.params.SharedSecretSize])
  93. pub.affine_xQmP.ToBytes(output[2*pub.params.SharedSecretSize : 3*pub.params.SharedSecretSize])
  94. return output
  95. }
  96. // Size returns size of the public key in bytes
  97. func (pub *PublicKey) Size() int {
  98. return pub.params.PublicKeySize
  99. }
  100. // Exports currently stored key. In case structure hasn't been filled with key data
  101. // returned byte string is filled with zeros.
  102. func (prv *PrivateKey) Export() []byte {
  103. ret := make([]byte, len(prv.Scalar)+len(prv.S))
  104. copy(ret, prv.S)
  105. copy(ret[len(prv.S):], prv.Scalar)
  106. return ret
  107. }
  108. // Size returns size of the private key in bytes
  109. func (prv *PrivateKey) Size() int {
  110. tmp := prv.params.SecretKeySize
  111. if prv.Variant() == KeyVariant_SIKE {
  112. tmp += int(prv.params.MsgLen)
  113. }
  114. return tmp
  115. }
  116. // Import clears content of the private key currently stored in the structure
  117. // and imports key from octet string. In case of SIKE, the random value 'S'
  118. // must be prepended to the value of actual private key (see SIKE spec for details).
  119. // Function doesn't import public key value to PrivateKey object.
  120. func (prv *PrivateKey) Import(input []byte) error {
  121. if len(input) != prv.Size() {
  122. return errors.New("sidh: input to short")
  123. }
  124. if len(prv.Scalar) != prv.params.SecretKeySize {
  125. return errors.New("sidh: object wrongly initialized")
  126. }
  127. copy(prv.S, input[:len(prv.S)])
  128. copy(prv.Scalar, input[len(prv.S):])
  129. return nil
  130. }
  131. // Generates random private key for SIDH or SIKE. Returns error
  132. // in case user provided RNG or memory initialization fails.
  133. func (prv *PrivateKey) Generate(rand io.Reader) error {
  134. var err error
  135. if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
  136. err = prv.generatePrivateKeyA(rand)
  137. } else {
  138. err = prv.generatePrivateKeyB(rand)
  139. }
  140. if prv.keyVariant == KeyVariant_SIKE && err == nil {
  141. _, err = io.ReadFull(rand, prv.S)
  142. }
  143. return err
  144. }
  145. // Generates public key.
  146. //
  147. // Constant time.
  148. func (prv *PrivateKey) GeneratePublicKey() (*PublicKey) {
  149. if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
  150. return publicKeyGenA(prv)
  151. }
  152. return publicKeyGenB(prv)
  153. }
  154. // Computes a shared secret which is a j-invariant. Function requires that pub has
  155. // different KeyVariant than prv. Length of returned output is 2*ceil(log_2 P)/8),
  156. // where P is a prime defining finite field.
  157. //
  158. // It's important to notice that each keypair must not be used more than once
  159. // to calculate shared secret.
  160. //
  161. // Function may return error. This happens only in case provided input is invalid.
  162. // Constant time for properly initialized private and public key.
  163. func DeriveSecret(prv *PrivateKey, pub *PublicKey) ([]byte, error) {
  164. if (pub == nil) || (prv == nil) {
  165. return nil, errors.New("sidh: invalid arguments")
  166. }
  167. if (pub.keyVariant == prv.keyVariant) || (pub.params.Id != prv.params.Id) {
  168. return nil, errors.New("sidh: public and private are incompatbile")
  169. }
  170. if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
  171. return deriveSecretA(prv, pub), nil
  172. } else {
  173. return deriveSecretB(prv, pub), nil
  174. }
  175. }