You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

381 lines
11 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. // Package babyjub eddsa implements the EdDSA over the BabyJubJub curve
  2. //
  3. //nolint:gomnd
  4. package babyjub
  5. import (
  6. "crypto/rand"
  7. "database/sql/driver"
  8. "fmt"
  9. "math/big"
  10. "github.com/iden3/go-iden3-crypto/mimc7"
  11. "github.com/iden3/go-iden3-crypto/poseidon"
  12. "github.com/iden3/go-iden3-crypto/utils"
  13. )
  14. // pruneBuffer prunes the buffer during key generation according to RFC 8032.
  15. // https://tools.ietf.org/html/rfc8032#page-13
  16. func pruneBuffer(buf *[32]byte) *[32]byte {
  17. buf[0] &= 0xF8
  18. buf[31] &= 0x7F
  19. buf[31] |= 0x40
  20. return buf
  21. }
  22. // PrivateKey is an EdDSA private key, which is a 32byte buffer.
  23. type PrivateKey [32]byte
  24. // NewRandPrivKey generates a new random private key (using cryptographically
  25. // secure randomness).
  26. func NewRandPrivKey() PrivateKey {
  27. var k PrivateKey
  28. _, err := rand.Read(k[:])
  29. if err != nil {
  30. panic(err)
  31. }
  32. return k
  33. }
  34. // Scalar converts a private key into the scalar value s following the EdDSA
  35. // standard, and using blake-512 hash.
  36. func (k *PrivateKey) Scalar() *PrivKeyScalar {
  37. s := SkToBigInt(k)
  38. return NewPrivKeyScalar(s)
  39. }
  40. // SkToBigInt converts a private key into the *big.Int value following the
  41. // EdDSA standard, and using blake-512 hash
  42. func SkToBigInt(k *PrivateKey) *big.Int {
  43. sBuf := Blake512(k[:])
  44. sBuf32 := [32]byte{}
  45. copy(sBuf32[:], sBuf[:32])
  46. pruneBuffer(&sBuf32)
  47. s := new(big.Int)
  48. utils.SetBigIntFromLEBytes(s, sBuf32[:])
  49. s.Rsh(s, 3)
  50. return s
  51. }
  52. // Public returns the public key corresponding to a private key.
  53. func (k *PrivateKey) Public() *PublicKey {
  54. return k.Scalar().Public()
  55. }
  56. // PrivKeyScalar represents the scalar s output of a private key
  57. type PrivKeyScalar big.Int
  58. // NewPrivKeyScalar creates a new PrivKeyScalar from a big.Int
  59. func NewPrivKeyScalar(s *big.Int) *PrivKeyScalar {
  60. sk := PrivKeyScalar(*s)
  61. return &sk
  62. }
  63. // Public returns the public key corresponding to the scalar value s of a
  64. // private key.
  65. func (s *PrivKeyScalar) Public() *PublicKey {
  66. p := NewPoint().Mul((*big.Int)(s), B8)
  67. pk := PublicKey(*p)
  68. return &pk
  69. }
  70. // BigInt returns the big.Int corresponding to a PrivKeyScalar.
  71. func (s *PrivKeyScalar) BigInt() *big.Int {
  72. return (*big.Int)(s)
  73. }
  74. // PublicKey represents an EdDSA public key, which is a curve point.
  75. type PublicKey Point
  76. // MarshalText implements the marshaler for PublicKey
  77. func (pk PublicKey) MarshalText() ([]byte, error) {
  78. pkc := pk.Compress()
  79. return utils.Hex(pkc[:]).MarshalText()
  80. }
  81. // String returns the string representation of the PublicKey
  82. func (pk PublicKey) String() string {
  83. pkc := pk.Compress()
  84. return utils.Hex(pkc[:]).String()
  85. }
  86. // UnmarshalText implements the unmarshaler for the PublicKey
  87. func (pk *PublicKey) UnmarshalText(h []byte) error {
  88. var pkc PublicKeyComp
  89. if err := utils.HexDecodeInto(pkc[:], h); err != nil {
  90. return err
  91. }
  92. pkd, err := pkc.Decompress()
  93. if err != nil {
  94. return err
  95. }
  96. *pk = *pkd
  97. return nil
  98. }
  99. // Point returns the Point corresponding to a PublicKey.
  100. func (pk *PublicKey) Point() *Point {
  101. return (*Point)(pk)
  102. }
  103. // PublicKeyComp represents a compressed EdDSA Public key; it's a compressed curve
  104. // point.
  105. type PublicKeyComp [32]byte
  106. // MarshalText implements the marshaler for the PublicKeyComp
  107. func (pkComp PublicKeyComp) MarshalText() ([]byte, error) {
  108. return utils.Hex(pkComp[:]).MarshalText()
  109. }
  110. // String returns the string representation of the PublicKeyComp
  111. func (pkComp PublicKeyComp) String() string { return utils.Hex(pkComp[:]).String() }
  112. // UnmarshalText implements the unmarshaler for the PublicKeyComp
  113. func (pkComp *PublicKeyComp) UnmarshalText(h []byte) error {
  114. return utils.HexDecodeInto(pkComp[:], h)
  115. }
  116. // Compress returns the PublicKeyCompr for the given PublicKey
  117. func (pk *PublicKey) Compress() PublicKeyComp {
  118. return PublicKeyComp((*Point)(pk).Compress())
  119. }
  120. // Decompress returns the PublicKey for the given PublicKeyComp
  121. func (pkComp *PublicKeyComp) Decompress() (*PublicKey, error) {
  122. point, err := NewPoint().Decompress(*pkComp)
  123. if err != nil {
  124. return nil, err
  125. }
  126. pk := PublicKey(*point)
  127. return &pk, nil
  128. }
  129. // Signature represents an EdDSA uncompressed signature.
  130. type Signature struct {
  131. R8 *Point
  132. S *big.Int
  133. }
  134. // SignatureComp represents a compressed EdDSA signature.
  135. type SignatureComp [64]byte
  136. // MarshalText implements the marshaler for the SignatureComp
  137. func (sComp SignatureComp) MarshalText() ([]byte, error) {
  138. return utils.Hex(sComp[:]).MarshalText()
  139. }
  140. // String returns the string representation of the SignatureComp
  141. func (sComp SignatureComp) String() string { return utils.Hex(sComp[:]).String() }
  142. // UnmarshalText implements the unmarshaler for the SignatureComp
  143. func (sComp *SignatureComp) UnmarshalText(h []byte) error {
  144. return utils.HexDecodeInto(sComp[:], h)
  145. }
  146. // Compress an EdDSA signature by concatenating the compression of
  147. // the point R8 and the Little-Endian encoding of S.
  148. func (s *Signature) Compress() SignatureComp {
  149. R8p := s.R8.Compress()
  150. Sp := utils.BigIntLEBytes(s.S)
  151. buf := [64]byte{}
  152. copy(buf[:32], R8p[:])
  153. copy(buf[32:], Sp[:])
  154. return SignatureComp(buf)
  155. }
  156. // Decompress a compressed signature into s, and also returns the decompressed
  157. // signature. Returns error if the Point decompression fails.
  158. func (s *Signature) Decompress(buf [64]byte) (*Signature, error) {
  159. R8p := [32]byte{}
  160. copy(R8p[:], buf[:32])
  161. var err error
  162. if s.R8, err = NewPoint().Decompress(R8p); err != nil {
  163. return nil, err
  164. }
  165. s.S = utils.SetBigIntFromLEBytes(new(big.Int), buf[32:])
  166. return s, nil
  167. }
  168. // Decompress a compressed signature. Returns error if the Point decompression
  169. // fails.
  170. func (sComp *SignatureComp) Decompress() (*Signature, error) {
  171. return new(Signature).Decompress(*sComp)
  172. }
  173. // Scan implements Scanner for database/sql.
  174. func (sComp *SignatureComp) Scan(src interface{}) error {
  175. srcB, ok := src.([]byte)
  176. if !ok {
  177. return fmt.Errorf("can't scan %T into Signature", src)
  178. }
  179. if len(srcB) != 64 {
  180. return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64)
  181. }
  182. copy(sComp[:], srcB)
  183. return nil
  184. }
  185. // Value implements valuer for database/sql.
  186. func (sComp SignatureComp) Value() (driver.Value, error) {
  187. return sComp[:], nil
  188. }
  189. // Scan implements Scanner for database/sql.
  190. func (s *Signature) Scan(src interface{}) error {
  191. srcB, ok := src.([]byte)
  192. if !ok {
  193. return fmt.Errorf("can't scan %T into Signature", src)
  194. }
  195. if len(srcB) != 64 {
  196. return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64)
  197. }
  198. buf := [64]byte{}
  199. copy(buf[:], srcB)
  200. _, err := s.Decompress(buf)
  201. return err
  202. }
  203. // Value implements valuer for database/sql.
  204. func (s Signature) Value() (driver.Value, error) {
  205. comp := s.Compress()
  206. return comp[:], nil
  207. }
  208. // SignMimc7 signs a message encoded as a big.Int in Zq using blake-512 hash
  209. // for buffer hashing and mimc7 for big.Int hashing.
  210. func (k *PrivateKey) SignMimc7(msg *big.Int) (*Signature, error) {
  211. h1 := Blake512(k[:])
  212. msgBuf := utils.BigIntLEBytes(msg)
  213. msgBuf32 := [32]byte{}
  214. copy(msgBuf32[:], msgBuf[:])
  215. rBuf := Blake512(append(h1[32:], msgBuf32[:]...))
  216. r := utils.SetBigIntFromLEBytes(new(big.Int), rBuf) // r = H(H_{32..63}(k), msg)
  217. r.Mod(r, SubOrder)
  218. R8 := NewPoint().Mul(r, B8) // R8 = r * 8 * B
  219. A := k.Public().Point()
  220. hmInput := []*big.Int{R8.X, R8.Y, A.X, A.Y, msg}
  221. hm, err := mimc7.Hash(hmInput, nil) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
  222. if err != nil {
  223. return nil, err
  224. }
  225. S := new(big.Int).Lsh(k.Scalar().BigInt(), 3)
  226. S = S.Mul(hm, S)
  227. S.Add(r, S)
  228. S.Mod(S, SubOrder) // S = r + hm * 8 * s
  229. return &Signature{R8: R8, S: S}, nil
  230. }
  231. // VerifyMimc7 verifies the signature of a message encoded as a big.Int in Zq
  232. // using blake-512 hash for buffer hashing and mimc7 for big.Int hashing.
  233. func (pk *PublicKey) VerifyMimc7(msg *big.Int, sig *Signature) error {
  234. hmInput := []*big.Int{sig.R8.X, sig.R8.Y, pk.X, pk.Y, msg}
  235. hm, err := mimc7.Hash(hmInput, nil) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
  236. if err != nil {
  237. return err
  238. }
  239. left := NewPoint().Mul(sig.S, B8) // left = s * 8 * B
  240. r1 := big.NewInt(8)
  241. r1.Mul(r1, hm)
  242. right := NewPoint().Mul(r1, pk.Point())
  243. rightProj := right.Projective()
  244. rightProj.Add(sig.R8.Projective(), rightProj) // right = 8 * R + 8 * hm * A
  245. right = rightProj.Affine()
  246. if (left.X.Cmp(right.X) == 0) && (left.Y.Cmp(right.Y) == 0) {
  247. return nil
  248. }
  249. return fmt.Errorf("verifyMimc7 failed")
  250. }
  251. // SignPoseidon signs a message encoded as a big.Int in Zq using blake-512 hash
  252. // for buffer hashing and Poseidon for big.Int hashing.
  253. func (k *PrivateKey) SignPoseidon(msg *big.Int) (*Signature, error) {
  254. h1 := Blake512(k[:])
  255. msgBuf := utils.BigIntLEBytes(msg)
  256. msgBuf32 := [32]byte{}
  257. copy(msgBuf32[:], msgBuf[:])
  258. rBuf := Blake512(append(h1[32:], msgBuf32[:]...))
  259. r := utils.SetBigIntFromLEBytes(new(big.Int), rBuf) // r = H(H_{32..63}(k), msg)
  260. r.Mod(r, SubOrder)
  261. R8 := NewPoint().Mul(r, B8) // R8 = r * 8 * B
  262. A := k.Public().Point()
  263. hmInput := []*big.Int{R8.X, R8.Y, A.X, A.Y, msg}
  264. hm, err := poseidon.Hash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
  265. if err != nil {
  266. return nil, err
  267. }
  268. S := new(big.Int).Lsh(k.Scalar().BigInt(), 3)
  269. S = S.Mul(hm, S)
  270. S.Add(r, S)
  271. S.Mod(S, SubOrder) // S = r + hm * 8 * s
  272. return &Signature{R8: R8, S: S}, nil
  273. }
  274. // VerifyPoseidon verifies the signature of a message encoded as a big.Int in Zq
  275. // using blake-512 hash for buffer hashing and Poseidon for big.Int hashing.
  276. func (pk *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) error {
  277. hmInput := []*big.Int{sig.R8.X, sig.R8.Y, pk.X, pk.Y, msg}
  278. hm, err := poseidon.Hash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
  279. if err != nil {
  280. return err
  281. }
  282. left := NewPoint().Mul(sig.S, B8) // left = s * 8 * B
  283. r1 := big.NewInt(8)
  284. r1.Mul(r1, hm)
  285. right := NewPoint().Mul(r1, pk.Point())
  286. rightProj := right.Projective()
  287. rightProj.Add(sig.R8.Projective(), rightProj) // right = 8 * R + 8 * hm * A
  288. right = rightProj.Affine()
  289. if (left.X.Cmp(right.X) == 0) && (left.Y.Cmp(right.Y) == 0) {
  290. return nil
  291. }
  292. return fmt.Errorf("verifyPoseidon failed")
  293. }
  294. // Scan implements Scanner for database/sql.
  295. func (pk *PublicKey) Scan(src interface{}) error {
  296. srcB, ok := src.([]byte)
  297. if !ok {
  298. return fmt.Errorf("can't scan %T into PublicKey", src)
  299. }
  300. if len(srcB) != 32 {
  301. return fmt.Errorf("can't scan []byte of len %d into PublicKey, want %d", len(srcB), 32)
  302. }
  303. var comp PublicKeyComp
  304. copy(comp[:], srcB)
  305. decomp, err := comp.Decompress()
  306. if err != nil {
  307. return err
  308. }
  309. *pk = *decomp
  310. return nil
  311. }
  312. // Value implements valuer for database/sql.
  313. func (pk PublicKey) Value() (driver.Value, error) {
  314. comp := pk.Compress()
  315. return comp[:], nil
  316. }
  317. // Scan implements Scanner for database/sql.
  318. func (pkComp *PublicKeyComp) Scan(src interface{}) error {
  319. srcB, ok := src.([]byte)
  320. if !ok {
  321. return fmt.Errorf("can't scan %T into PublicKeyComp", src)
  322. }
  323. if len(srcB) != 32 {
  324. return fmt.Errorf("can't scan []byte of len %d into PublicKeyComp, want %d", len(srcB), 32)
  325. }
  326. copy(pkComp[:], srcB)
  327. return nil
  328. }
  329. // Value implements valuer for database/sql.
  330. func (pkComp PublicKeyComp) Value() (driver.Value, error) {
  331. return pkComp[:], nil
  332. }