Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

224 linhas
6.8 KiB

  1. package sidh
  2. import (
  3. "errors"
  4. "io"
  5. . "github.com/cloudflare/p751sidh/internal/isogeny"
  6. )
  7. // Id's correspond to bitlength of the prime field characteristic
  8. // Currently FP_751 is the only one supported by this implementation
  9. const (
  10. FP_503 PrimeFieldId = iota
  11. FP_751
  12. FP_964
  13. maxPrimeFieldId
  14. )
  15. const (
  16. // First 2 bits identify SIDH variant third bit indicates
  17. // wether key is a SIKE variant (set) or SIDH (not set)
  18. // 001 - SIDH: corresponds to 2-torsion group
  19. KeyVariant_SIDH_A KeyVariant = 1 << 0
  20. // 010 - SIDH: corresponds to 3-torsion group
  21. KeyVariant_SIDH_B = 1 << 1
  22. // 110 - SIKE
  23. KeyVariant_SIKE = 1<<2 | KeyVariant_SIDH_B
  24. )
  25. // Base type for public and private key. Used mainly to carry domain
  26. // parameters.
  27. type key struct {
  28. // Domain parameters of the algorithm to be used with a key
  29. params *SidhParams
  30. // Flag indicates wether corresponds to 2-, 3-torsion group or SIKE
  31. keyVariant KeyVariant
  32. }
  33. // Defines operations on public key
  34. type PublicKey struct {
  35. key
  36. affine_xP Fp2Element
  37. affine_xQ Fp2Element
  38. affine_xQmP Fp2Element
  39. }
  40. // Defines operations on private key
  41. type PrivateKey struct {
  42. key
  43. // Secret key
  44. Scalar []byte
  45. // Used only by KEM
  46. S []byte
  47. }
  48. // Accessor to the domain parameters
  49. func (key *key) Params() *SidhParams {
  50. return key.params
  51. }
  52. // Accessor to key variant
  53. func (key *key) Variant() KeyVariant {
  54. return key.keyVariant
  55. }
  56. // NewPrivateKey initializes private key.
  57. // Usage of this function guarantees that the object is correctly initialized.
  58. func NewPrivateKey(id PrimeFieldId, v KeyVariant) *PrivateKey {
  59. prv := &PrivateKey{key: key{params: Params(id), keyVariant: v}}
  60. if (v & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
  61. prv.Scalar = make([]byte, prv.params.A.SecretByteLen)
  62. } else {
  63. prv.Scalar = make([]byte, prv.params.B.SecretByteLen)
  64. }
  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. op := CurveOperations{Params: pub.params}
  83. ssSz := pub.params.SharedSecretSize
  84. op.Fp2FromBytes(&pub.affine_xP, input[0:ssSz])
  85. op.Fp2FromBytes(&pub.affine_xQ, input[ssSz:2*ssSz])
  86. op.Fp2FromBytes(&pub.affine_xQmP, input[2*ssSz:3*ssSz])
  87. return nil
  88. }
  89. // Exports currently stored key. In case structure hasn't been filled with key data
  90. // returned byte string is filled with zeros.
  91. func (pub *PublicKey) Export() []byte {
  92. output := make([]byte, pub.params.PublicKeySize)
  93. op := CurveOperations{Params: pub.params}
  94. ssSz := pub.params.SharedSecretSize
  95. op.Fp2ToBytes(output[0:ssSz], &pub.affine_xP)
  96. op.Fp2ToBytes(output[ssSz:2*ssSz], &pub.affine_xQ)
  97. op.Fp2ToBytes(output[2*ssSz:3*ssSz], &pub.affine_xQmP)
  98. return output
  99. }
  100. // Size returns size of the public key in bytes
  101. func (pub *PublicKey) Size() int {
  102. return pub.params.PublicKeySize
  103. }
  104. // Exports currently stored key. In case structure hasn't been filled with key data
  105. // returned byte string is filled with zeros.
  106. func (prv *PrivateKey) Export() []byte {
  107. ret := make([]byte, len(prv.Scalar)+len(prv.S))
  108. copy(ret, prv.S)
  109. copy(ret[len(prv.S):], prv.Scalar)
  110. return ret
  111. }
  112. // Size returns size of the private key in bytes
  113. func (prv *PrivateKey) Size() int {
  114. tmp := len(prv.Scalar)
  115. if prv.Variant() == KeyVariant_SIKE {
  116. tmp += int(prv.params.MsgLen)
  117. }
  118. return tmp
  119. }
  120. // Import clears content of the private key currently stored in the structure
  121. // and imports key from octet string. In case of SIKE, the random value 'S'
  122. // must be prepended to the value of actual private key (see SIKE spec for details).
  123. // Function doesn't import public key value to PrivateKey object.
  124. func (prv *PrivateKey) Import(input []byte) error {
  125. if len(input) != prv.Size() {
  126. return errors.New("sidh: input to short")
  127. }
  128. copy(prv.S, input[:len(prv.S)])
  129. copy(prv.Scalar, input[len(prv.S):])
  130. return nil
  131. }
  132. // Generates random private key for SIDH or SIKE. Generated value is
  133. // formed as little-endian integer from key-space <2^(e2-1)..2^e2 - 1>
  134. // for KeyVariant_A or <2^(s-1)..2^s - 1>, where s = floor(log_2(3^e3)),
  135. // for KeyVariant_B.
  136. //
  137. // Returns error in case user provided RNG fails.
  138. func (prv *PrivateKey) Generate(rand io.Reader) error {
  139. var err error
  140. var dp *DomainParams
  141. if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
  142. dp = &prv.params.A
  143. } else {
  144. dp = &prv.params.B
  145. }
  146. if prv.keyVariant == KeyVariant_SIKE && err == nil {
  147. _, err = io.ReadFull(rand, prv.S)
  148. }
  149. // Private key generation takes advantage of the fact that keyspace for secret
  150. // key is (0, 2^x - 1), for some possitivite value of 'x' (see SIKE, 1.3.8).
  151. // It means that all bytes in the secret key, but the last one, can take any
  152. // value between <0x00,0xFF>. Similarily for the last byte, but generation
  153. // needs to chop off some bits, to make sure generated value is an element of
  154. // a key-space.
  155. _, err = io.ReadFull(rand, prv.Scalar)
  156. if err != nil {
  157. return err
  158. }
  159. prv.Scalar[len(prv.Scalar)-1] &= (1 << (dp.SecretBitLen % 8)) - 1
  160. // Make sure scalar is SecretBitLen long. SIKE spec says that key
  161. // space starts from 0, but I'm not confortable with having low
  162. // value scalars used for private keys. It is still secrure as per
  163. // table 5.1 in [SIKE].
  164. prv.Scalar[len(prv.Scalar)-1] |= 1 << ((dp.SecretBitLen % 8) - 1)
  165. return err
  166. }
  167. // Generates public key.
  168. //
  169. // Constant time.
  170. func (prv *PrivateKey) GeneratePublicKey() (*PublicKey) {
  171. if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
  172. return publicKeyGenA(prv)
  173. }
  174. return publicKeyGenB(prv)
  175. }
  176. // Computes a shared secret which is a j-invariant. Function requires that pub has
  177. // different KeyVariant than prv. Length of returned output is 2*ceil(log_2 P)/8),
  178. // where P is a prime defining finite field.
  179. //
  180. // It's important to notice that each keypair must not be used more than once
  181. // to calculate shared secret.
  182. //
  183. // Function may return error. This happens only in case provided input is invalid.
  184. // Constant time for properly initialized private and public key.
  185. func DeriveSecret(prv *PrivateKey, pub *PublicKey) ([]byte, error) {
  186. if (pub == nil) || (prv == nil) {
  187. return nil, errors.New("sidh: invalid arguments")
  188. }
  189. if (pub.keyVariant == prv.keyVariant) || (pub.params.Id != prv.params.Id) {
  190. return nil, errors.New("sidh: public and private are incompatbile")
  191. }
  192. if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
  193. return deriveSecretA(prv, pub), nil
  194. } else {
  195. return deriveSecretB(prv, pub), nil
  196. }
  197. }