Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/google/uuid v1.6.0
github.com/json-iterator/go v1.1.12
github.com/mr-tron/base58 v1.2.0
github.com/oasisprotocol/curve25519-voi v0.0.0-20251114093237-2ab5a27a1729
go.mongodb.org/mongo-driver/v2 v2.5.0
)

Expand Down Expand Up @@ -61,7 +62,6 @@ require (
)

require (
filippo.io/edwards25519 v1.2.0
github.com/AlekSi/pointer v1.2.0
github.com/buger/jsonparser v1.1.2
github.com/davecgh/go-spew v1.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIi
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w=
github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
Expand Down Expand Up @@ -106,6 +104,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oasisprotocol/curve25519-voi v0.0.0-20251114093237-2ab5a27a1729 h1:yfQ2sO9WJXUAIUR+g7NUkxJSKCAFJcR5sUDu+ZmjTZI=
github.com/oasisprotocol/curve25519-voi v0.0.0-20251114093237-2ab5a27a1729/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
Expand Down
60 changes: 26 additions & 34 deletions keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package solana
import (
"bytes"
"crypto"
"crypto/ed25519"
crypto_rand "crypto/rand"
"crypto/sha256"
"errors"
Expand All @@ -29,9 +28,10 @@ import (
"os"
"sort"

"filippo.io/edwards25519/field"
"github.com/gagliardetto/solana-go/base58"
mrtronbase58 "github.com/mr-tron/base58"
"github.com/oasisprotocol/curve25519-voi/curve"
voied25519 "github.com/oasisprotocol/curve25519-voi/primitives/ed25519"
"go.mongodb.org/mongo-driver/v2/bson"
)

Expand Down Expand Up @@ -69,14 +69,14 @@ func PrivateKeyFromBase58(privkey string) (PrivateKey, error) {
}

func ValidatePrivateKey(b []byte) (bool, error) {
if len(b) != ed25519.PrivateKeySize {
return false, fmt.Errorf("invalid private key size, expected %v, got %d", ed25519.PrivateKeySize, len(b))
if len(b) != voied25519.PrivateKeySize {
return false, fmt.Errorf("invalid private key size, expected %v, got %d", voied25519.PrivateKeySize, len(b))
}

// ed25519 private keys are seed(32) + public(32); ensure they match.
derived := ed25519.NewKeyFromSeed(b[:ed25519.SeedSize])
derived := voied25519.NewKeyFromSeed(b[:voied25519.SeedSize])
if !bytes.Equal(derived, b) {
if !IsOnCurve(b[ed25519.SeedSize:]) {
if !IsOnCurve(b[voied25519.SeedSize:]) {
return false, errors.New("invalid private key: seed/public key mismatch (provided public key is NOT on the ed25519 curve)")
}
return false, errors.New("invalid private key: seed/public key mismatch")
Expand Down Expand Up @@ -114,7 +114,7 @@ func (k PrivateKey) String() string {
}

func NewRandomPrivateKey() (PrivateKey, error) {
pub, priv, err := ed25519.GenerateKey(crypto_rand.Reader)
pub, priv, err := voied25519.GenerateKey(crypto_rand.Reader)
if err != nil {
return nil, err
}
Expand All @@ -127,7 +127,7 @@ func (k PrivateKey) Sign(payload []byte) (Signature, error) {
if err := k.Validate(); err != nil {
return Signature{}, err
}
p := ed25519.PrivateKey(k)
p := voied25519.PrivateKey(k)
signData, err := p.Sign(crypto_rand.Reader, payload, crypto.Hash(0))
if err != nil {
return Signature{}, err
Expand All @@ -144,8 +144,8 @@ func (k PrivateKey) PublicKey() PublicKey {
panic(err)
}

p := ed25519.PrivateKey(k)
pub := p.Public().(ed25519.PublicKey)
p := voied25519.PrivateKey(k)
pub := p.Public().(voied25519.PublicKey)

var publicKey PublicKey
copy(publicKey[:], pub)
Expand All @@ -156,9 +156,13 @@ func (k PrivateKey) PublicKey() PublicKey {
// PK is a convenience alias for PublicKey
type PK = PublicKey

// done to keep verify the same as stdlib crypto/ed25519
var verifyOptsStdLib = &voied25519.Options{
Verify: voied25519.VerifyOptionsStdLib,
}

func (p PublicKey) Verify(message []byte, signature Signature) bool {
pub := ed25519.PublicKey(p[:])
return ed25519.Verify(pub, message, signature[:])
return voied25519.VerifyWithOptions(p[:], message, signature[:], verifyOptsStdLib)
}

type PublicKey [PublicKeyLength]byte
Expand Down Expand Up @@ -300,7 +304,7 @@ func (p PublicKey) Bytes() []byte {
return []byte(p[:])
}

// Check if a `Pubkey` is on the ed25519 curve.
// Check if a `Pubkey` is on the voied25519 curve.
func (p PublicKey) IsOnCurve() bool {
return IsOnCurve(p[:])
}
Expand Down Expand Up @@ -621,7 +625,7 @@ const (
SignatureLength = 64

// Number of bytes in a private key.
PrivateKeyLength = ed25519.PrivateKeySize
PrivateKeyLength = voied25519.PrivateKeySize

// // Maximum string length of a base58 encoded pubkey.
// MaxBase58Length = 44
Expand Down Expand Up @@ -682,32 +686,20 @@ func CreateProgramAddress(seeds [][]byte, programID PublicKey) (PublicKey, error
return PublicKeyFromBytes(hash[:]), nil
}

var feOne = new(field.Element).One()
var d, _ = new(field.Element).SetBytes([]byte{
0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52})

// Check if the provided `b` is on the ed25519 curve.
func IsOnCurve(b []byte) bool {
if len(b) != ed25519.PublicKeySize {
if len(b) != voied25519.PublicKeySize {
return false
}
//_, err := new(edwards25519.Point).SetBytes(b)
y, err := new(field.Element).SetBytes(b)
if err != nil {
var compressed curve.CompressedEdwardsY
if _, err := compressed.SetBytes(b); err != nil {
return false
}

y2 := new(field.Element).Square(y)
u := new(field.Element).Subtract(y2, feOne)

vv := new(field.Element).Multiply(y2, d)
vv = vv.Add(vv, feOne)

_, wasSquare := new(field.Element).SqrtRatio(u, vv)
return wasSquare != 0
var p curve.EdwardsPoint
if _, err := p.SetCompressedY(&compressed); err != nil {
return false
}
return true
}

// Find a valid program address and its corresponding bump seed.
Expand Down
5 changes: 3 additions & 2 deletions nativetypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
package solana

import (
"crypto/ed25519"
"encoding/base64"
"fmt"
"io"

voied25519 "github.com/oasisprotocol/curve25519-voi/primitives/ed25519"

bin "github.com/gagliardetto/binary"
"github.com/gagliardetto/solana-go/base58"
"github.com/mostynb/zstdpool-freelist"
Expand Down Expand Up @@ -186,7 +187,7 @@ func (p *Signature) UnmarshalJSON(data []byte) (err error) {

// Verify checks that the signature is valid for the given public key and message.
func (s Signature) Verify(pubkey PublicKey, msg []byte) bool {
return ed25519.Verify(pubkey[:], msg, s[:])
return voied25519.VerifyWithOptions(pubkey[:], msg, s[:], verifyOptsStdLib)
}

func (p Signature) String() string {
Expand Down
Loading