1 // Copyright (c) 2015-2021 The btcsuite developers
2 // Copyright (c) 2015-2021 The Decred developers
3 4 package btcec
5 6 import (
7 "fmt"
8 9 "smesh.lol/pkg/nostr/ec/secp256k1"
10 )
11 12 // JacobianPoint is an element of the group formed by the secp256k1 curve in
13 // Jacobian projective coordinates and thus represents a point on the curve.
14 type JacobianPoint = secp256k1.JacobianPoint
15 16 // infinityPoint is the jacobian representation of the point at infinity.
17 var infinityPoint JacobianPoint
18 19 // MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z
20 // coordinates.
21 func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint {
22 return secp256k1.MakeJacobianPoint(x, y, z)
23 }
24 25 // AddNonConst adds the passed Jacobian points together and stores the result
26 // in the provided result param in *non-constant* time.
27 func AddNonConst(p1, p2, result *JacobianPoint) {
28 secp256k1.AddNonConst(p1, p2, result)
29 }
30 31 // DecompressY attempts to calculate the Y coordinate for the given X
32 // coordinate such that the result pair is a point on the secp256k1 curve. It
33 // adjusts Y based on the desired oddness and returns whether or not it was
34 // successful since not all X coordinates are valid.
35 //
36 // The magnitude of the provided X coordinate field val must be a max of 8 for
37 // a correct result. The resulting Y field val will have a max magnitude of 2.
38 func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool {
39 return secp256k1.DecompressY(x, odd, resultY)
40 }
41 42 // DoubleNonConst doubles the passed Jacobian point and stores the result in
43 // the provided result parameter in *non-constant* time.
44 //
45 // NOTE: The point must be normalized for this function to return the correct
46 // result. The resulting point will be normalized.
47 func DoubleNonConst(p, result *JacobianPoint) {
48 secp256k1.DoubleNonConst(p, result)
49 }
50 51 // ScalarBaseMultNonConst multiplies k*G where G is the base point of the group
52 // and k is a big endian integer. The result is stored in Jacobian coordinates
53 // (x1, y1, z1).
54 //
55 // NOTE: The resulting point will be normalized.
56 func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) {
57 secp256k1.ScalarBaseMultNonConst(k, result)
58 }
59 60 // ScalarMultNonConst multiplies k*P where k is a big endian integer modulo the
61 // curve order and P is a point in Jacobian projective coordinates and stores
62 // the result in the provided Jacobian point.
63 //
64 // NOTE: The point must be normalized for this function to return the correct
65 // result. The resulting point will be normalized.
66 func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) {
67 secp256k1.ScalarMultNonConst(k, point, result)
68 }
69 70 // ParseJacobian parses a byte slice point as a secp256k1.Publickey and returns the
71 // pubkey as a JacobianPoint. If the nonce is a zero slice, the infinityPoint
72 // is returned.
73 func ParseJacobian(point []byte) (JacobianPoint, error) {
74 var result JacobianPoint
75 if len(point) != 33 {
76 str := fmt.Sprintf(
77 "invalid nonce: invalid length: %v",
78 len(point),
79 )
80 return JacobianPoint{}, makeError(secp256k1.ErrPubKeyInvalidLen, str)
81 }
82 if point[0] == 0x00 {
83 return infinityPoint, nil
84 }
85 noncePk, err := secp256k1.ParsePubKey(point)
86 if err != nil {
87 return JacobianPoint{}, err
88 }
89 noncePk.AsJacobian(&result)
90 return result, nil
91 }
92 93 // JacobianToByteSlice converts the passed JacobianPoint to a Pubkey
94 // and serializes that to a byte slice. If the JacobianPoint is the infinity
95 // point, a zero slice is returned.
96 func JacobianToByteSlice(point JacobianPoint) []byte {
97 if point.X == infinityPoint.X && point.Y == infinityPoint.Y {
98 return []byte{:33}
99 }
100 point.ToAffine()
101 return NewPublicKey(
102 &point.X, &point.Y,
103 ).SerializeCompressed()
104 }
105 106 // GeneratorJacobian sets the passed JacobianPoint to the Generator Point.
107 func GeneratorJacobian(jacobian *JacobianPoint) {
108 var k ModNScalar
109 k.SetInt(1)
110 ScalarBaseMultNonConst(&k, jacobian)
111 }
112