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.

332 lines
9.4 KiB

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