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.

374 lines
11 KiB

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