Closed mottla closed 6 years ago
I'm sure you don't need the answer anymore, as I see it's been a while, but I just now noticed this. The values being produced by your code are actually the same, they're just represented as the negative mod P. I modified your code slightly to mod the negation of the Y value of the point by P before the addition and to perform Px = P - Px
, and Py = P - Py
when the produced points aren't the same so the results match as you're expecting.
package main
import (
"crypto/elliptic"
"crypto/rand"
"fmt"
"io"
"math/big"
"github.com/decred/dcrd/dcrec/edwards"
)
var one = big.NewInt(1)
func RandFieldElement(c elliptic.Curve) (k *big.Int) {
params := c.Params()
b := make([]byte, params.BitSize/8+8)
_, err := io.ReadFull(rand.Reader, b)
if err != nil {
panic("random failed..")
}
b[0] &= 248
b[31] &= 127
b[31] |= 64
k = new(big.Int).SetBytes(b)
n := new(big.Int).Sub(params.N, one)
k.Mod(k, n)
k.Add(k, one)
return
}
func main() {
curve := edwards.Edwards()
//curve := elliptic.P256()
a := RandFieldElement(curve)
b := RandFieldElement(curve)
sum := new(big.Int).Sub(a, b)
sum.Mod(sum, curve.Params().N)
sGx, sGy := curve.ScalarBaseMult(sum.Bytes())
ax, ay := curve.ScalarBaseMult(a.Bytes())
bx, by := curve.ScalarBaseMult(b.Bytes())
negBy := new(big.Int).Neg(by)
negBy.Mod(negBy, curve.Params().P)
Px, Py := curve.Add(ax, ay, bx, negBy)
if sGx.Cmp(Px) != 0 {
Px.Sub(curve.Params().P, Px)
Py.Sub(curve.Params().P, Py)
}
fmt.Printf(" (a-b)G: %x %x\n", sGx, sGy)
fmt.Printf("aG - bG: %x %x\n", Px, Py)
}
Sample Output:
(a-b)G: 2c1998de8b5a9d5f485f2841a99838d9443ea8b297d1e28928043e80f0635c81 4b318b1887bd7ebc809893fc2a33daedd741b9ef954bc8fcd0299a7f90b0973c
aG - bG: 2c1998de8b5a9d5f485f2841a99838d9443ea8b297d1e28928043e80f0635c81 4b318b1887bd7ebc809893fc2a33daedd741b9ef954bc8fcd0299a7f90b0973c
(a-b)G: 5488eb2f7f9f42ba6c94bd1983dd177277d6e763518212c922d638bc85310277 167dde9fc5c9a048d21687285bb3e2a783e3a03c236137b14a3db042c7106960
aG - bG: 5488eb2f7f9f42ba6c94bd1983dd177277d6e763518212c922d638bc85310277 167dde9fc5c9a048d21687285bb3e2a783e3a03c236137b14a3db042c7106960
(a-b)G: 110b3ead7b493e655bc07b74c541e20aab6de22435d7eb346815350ec6620473 12b3f52acdf22066ad2db0e115d1b14094164fa6db7813d85a0651f62d1ef702
aG - bG: 110b3ead7b493e655bc07b74c541e20aab6de22435d7eb346815350ec6620473 12b3f52acdf22066ad2db0e115d1b14094164fa6db7813d85a0651f62d1ef702
HI! I'm writing a CryptoNote implementation for university using your edwards package. I try to check (a-b)G == aG-bG On the p256 it works, on the twisted edcurve, it does not. Can you tell me why? I'd be so thankful.. It worked before and now I did some code refactoring and suddenly experience this bug.. I reduced it up untill that point so far..
The code looks: func TestSub(t testing.T) { //curve := edwards.Edwards() curve:= elliptic.P256() alpha := RandFieldElement(curve) alpha2 := RandFieldElement(curve) sum := new(big.Int).Sub(alpha,alpha2) sum.Mod(sum,curve.Params().N) r1,:=curve.ScalarBaseMult(sum.Bytes()) fmt.Println(r1) aa1,aa2:=curve.ScalarBaseMult(alpha.Bytes()) aa3,aa4:=curve.ScalarBaseMult(alpha2.Bytes()) a1,:=curve.Add(aa1,aa2,aa3,aa4.Neg(aa4)) fmt.Println(a1) } where func RandFieldElement(c elliptic.Curve) (k big.Int) { params := c.Params() b := make([]byte, params.BitSize/8+8) _, err := io.ReadFull(rand.Reader, b) if err != nil { panic("random failed..") } b[0] &= 248 b[31] &= 127 b[31] |= 64 k = new(big.Int).SetBytes(b) n := new(big.Int).Sub(params.N, one) k.Mod(k, n) k.Add(k, one) return }