2025-10-09 15:10:39 -04:00
|
|
|
// Copyright 2013 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package extra25519
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
"crypto/sha512"
|
|
|
|
|
"testing"
|
|
|
|
|
|
2025-10-09 15:11:59 -04:00
|
|
|
"github.com/sonr-io/crypto/internal/ed25519/edwards25519"
|
2025-10-09 15:10:39 -04:00
|
|
|
"golang.org/x/crypto/curve25519"
|
|
|
|
|
"golang.org/x/crypto/ed25519"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestCurve25519Conversion(t *testing.T) {
|
|
|
|
|
public, private, _ := ed25519.GenerateKey(rand.Reader)
|
|
|
|
|
var pubBytes [32]byte
|
|
|
|
|
copy(pubBytes[:], public)
|
|
|
|
|
var privBytes [64]byte
|
|
|
|
|
copy(privBytes[:], private)
|
|
|
|
|
|
|
|
|
|
var curve25519Public, curve25519Public2, curve25519Private [32]byte
|
|
|
|
|
PrivateKeyToCurve25519(&curve25519Private, &privBytes)
|
|
|
|
|
curve25519.ScalarBaseMult(&curve25519Public, &curve25519Private)
|
|
|
|
|
|
|
|
|
|
if !PublicKeyToCurve25519(&curve25519Public2, &pubBytes) {
|
|
|
|
|
t.Fatalf("PublicKeyToCurve25519 failed")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bytes.Equal(curve25519Public[:], curve25519Public2[:]) {
|
|
|
|
|
t.Errorf(
|
|
|
|
|
"Values didn't match: curve25519 produced %x, conversion produced %x",
|
|
|
|
|
curve25519Public[:],
|
|
|
|
|
curve25519Public2[:],
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHashNoCollisions(t *testing.T) {
|
|
|
|
|
type intpair struct {
|
|
|
|
|
i int
|
|
|
|
|
j uint
|
|
|
|
|
}
|
|
|
|
|
rainbow := make(map[[32]byte]intpair)
|
|
|
|
|
N := 25
|
|
|
|
|
if testing.Short() {
|
|
|
|
|
N = 3
|
|
|
|
|
}
|
|
|
|
|
var h [32]byte
|
|
|
|
|
// NOTE: hash values 0b100000000000... and 0b00000000000... both map to
|
|
|
|
|
// the identity. this is a core part of the elligator function and not a
|
|
|
|
|
// collision we need to worry about because an attacker would need to find
|
|
|
|
|
// the preimages of these hashes to exploit it.
|
|
|
|
|
h[0] = 1
|
|
|
|
|
for i := 0; i < N; i++ {
|
|
|
|
|
for j := range uint(257) {
|
|
|
|
|
if j < 256 {
|
|
|
|
|
h[j>>3] ^= byte(1) << (j & 7)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var P edwards25519.ExtendedGroupElement
|
|
|
|
|
HashToEdwards(&P, &h)
|
|
|
|
|
var p [32]byte
|
|
|
|
|
P.ToBytes(&p)
|
|
|
|
|
if c, ok := rainbow[p]; ok {
|
|
|
|
|
t.Fatalf("found collision: (%d, %d) and (%d, %d)", i, j, c.i, c.j)
|
|
|
|
|
}
|
|
|
|
|
rainbow[p] = intpair{i, j}
|
|
|
|
|
|
|
|
|
|
if j < 256 {
|
|
|
|
|
h[j>>3] ^= byte(1) << (j & 7)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
hh := sha512.Sum512(h[:]) // this package already imports sha512
|
|
|
|
|
copy(h[:], hh[:])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestElligator(t *testing.T) {
|
|
|
|
|
var publicKey, publicKey2, publicKey3, representative, privateKey [32]byte
|
|
|
|
|
|
|
|
|
|
for range 1000 {
|
|
|
|
|
rand.Reader.Read(privateKey[:])
|
|
|
|
|
|
|
|
|
|
if !ScalarBaseMult(&publicKey, &representative, &privateKey) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
RepresentativeToPublicKey(&publicKey2, &representative)
|
|
|
|
|
if !bytes.Equal(publicKey[:], publicKey2[:]) {
|
|
|
|
|
t.Fatal("The resulting public key doesn't match the initial one.")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
curve25519.ScalarBaseMult(&publicKey3, &privateKey)
|
|
|
|
|
if !bytes.Equal(publicKey[:], publicKey3[:]) {
|
|
|
|
|
t.Fatal("The public key doesn't match the value that curve25519 produced.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func BenchmarkKeyGeneration(b *testing.B) {
|
|
|
|
|
var publicKey, representative, privateKey [32]byte
|
|
|
|
|
|
|
|
|
|
// Find the private key that results in a point that's in the image of the map.
|
|
|
|
|
for {
|
|
|
|
|
rand.Reader.Read(privateKey[:])
|
|
|
|
|
if ScalarBaseMult(&publicKey, &representative, &privateKey) {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for b.Loop() {
|
|
|
|
|
ScalarBaseMult(&publicKey, &representative, &privateKey)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func BenchmarkMap(b *testing.B) {
|
|
|
|
|
var publicKey, representative [32]byte
|
|
|
|
|
rand.Reader.Read(representative[:])
|
|
|
|
|
|
|
|
|
|
for b.Loop() {
|
|
|
|
|
RepresentativeToPublicKey(&publicKey, &representative)
|
|
|
|
|
}
|
|
|
|
|
}
|