Skip to content
Open
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: 0 additions & 2 deletions api/cashu/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cashu

import (
"errors"
"log"
)

var (
Expand Down Expand Up @@ -134,7 +133,6 @@ type ErrorResponse struct {

func ErrorCodeToResponse(code ErrorCode, detail *string) ErrorResponse {

log.Printf("\n code: %+v \n", code)
return ErrorResponse{
Code: code,
Error: code.String(),
Expand Down
111 changes: 111 additions & 0 deletions api/cashu/generate_blind_signature_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package cashu_test

import (
"encoding/hex"
"testing"

"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/chaincfg"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/lescuer97/nutmix/api/cashu"
localsigner "github.com/lescuer97/nutmix/internal/signer/local_signer"
"github.com/lescuer97/nutmix/pkg/crypto"
"github.com/tyler-smith/go-bip32"
)

func TestGenerateBlindSignatureAndCheckSignature(t *testing.T) {
keyBytes, err := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000001")
if err != nil {
t.Errorf("could not decode key %+v", err)
}
key, err := hdkeychain.NewMaster(keyBytes, &chaincfg.MainNetParams)
if err != nil {
t.Errorf("could not setup master key %+v", err)
}

seed := cashu.Seed{
Id: "id",
Unit: cashu.Sat.String(),
Version: 0,
InputFeePpk: 0,
Amounts: cashu.GetAmountsForKeysets(cashu.LegacyMaxKeysetAmount),
Legacy: true,
FinalExpiry: nil,
DerivationPath: "",
CreatedAt: 0,
Active: false,
IssuerVersion: nil,
}

generatedKeysets, err := localsigner.GenerateKeysets(key, seed)
if err != nil {
t.Errorf("could not generate keyset %+v", err)
}

walletKey, err := bip32.NewMasterKey([]byte("walletseed"))
if err != nil {
t.Errorf("could not setup wallet key %+v", err)
}

parsedKey := secp256k1.PrivKeyFromBytes(walletKey.Key)

// Create BlindedMessage
publicKeyBlindFactor, privateKeyBlindFactor, err := crypto.BlindMessage("secret", parsedKey)
if err != nil {
t.Errorf("could not create blindmessage %+v", err)
}

justPubkeys := []*secp256k1.PublicKey{}
for i := range generatedKeysets {
justPubkeys = append(justPubkeys, generatedKeysets[i].GetPubKey())
}

keysetId, err := localsigner.DeriveKeysetId(justPubkeys)
if err != nil {
t.Errorf("could not derive keyset id %+v", err)
}

blindMessage := cashu.BlindedMessage{
Amount: 1,
B_: cashu.WrappedPublicKey{PublicKey: publicKeyBlindFactor},
Id: keysetId,
Witness: "",
}

// Create BlindSignature
blindSignature, err := blindMessage.GenerateBlindSignature(generatedKeysets[1].PrivKey)
if err != nil {
t.Errorf("could GenerateBlindSignature %+v", err)
}

if blindSignature.C_.String() != "027184da18bdc8c225093c299062fe0a3658122db41e6ef72258b83df52709a6b6" {
t.Errorf("blindSignature is not correct. %v", blindSignature.C_.String())
}

if blindSignature.Id != "000fc082ba6bd376" {
t.Errorf("blindSignature id is not correct. %v", blindSignature.Id)
}

unblindedFactor := crypto.UnblindSignature(blindSignature.C_.PublicKey, privateKeyBlindFactor, generatedKeysets[1].PrivKey.PubKey())

proof := cashu.Proof{
Amount: 1,
C: cashu.WrappedPublicKey{PublicKey: unblindedFactor},
Secret: "secret",
Id: keysetId,
Y: cashu.WrappedPublicKey{PublicKey: nil},
Quote: nil,
Witness: "",
State: "",
SeenAt: 0,
}

proof, err = proof.HashSecretToCurve()
if err != nil {
t.Errorf("could not proof.HashSecretToCurve %+v", err)
}

if proof.Y.ToHex() != "025dccd27047d10d4900b8d2c4ea6795702c2d1fbe1d3fd0d1cd4b18776b12ddc0" {
t.Errorf("proof.Y is not correct")
}
}
9 changes: 5 additions & 4 deletions api/cashu/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import (
"github.com/tyler-smith/go-bip32"
)

const LegacyMaxKeysetAmount int = 64
const MaxKeysetAmount int = 32

// Deprecated: Use DeriveKeysetIdV2 instead. This function generates V1 keyset IDs which are less unique.
func DeriveKeysetId(keysets []*secp256k1.PublicKey) (string, error) {
concatBinaryArray := []byte{}
Expand Down Expand Up @@ -112,12 +115,10 @@ func GenerateKeysets(versionKey *bip32.Key, values []uint64, seed Seed) ([]MintK
return keysets, nil
}

const MaxKeysetAmount int = 64

func GetAmountsForKeysets() []uint64 {
func GetAmountsForKeysets(max_order int) []uint64 {
keys := make([]uint64, 0)

for i := 0; i < MaxKeysetAmount; i++ {
for i := 0; i < max_order; i++ {
keys = append(keys, uint64(math.Pow(2, float64(i))))
}
return keys
Expand Down
140 changes: 0 additions & 140 deletions api/cashu/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,146 +8,8 @@ import (

"github.com/btcsuite/btcd/btcec/v2"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/tyler-smith/go-bip32"
)

func TestGenerateKeysetsAndIdGeneration(t *testing.T) {
// setup key
key, err := bip32.NewMasterKey([]byte("seed"))
if err != nil {
t.Errorf("could not setup master key %+v", err)
}

seed := Seed{
Id: "id",
Unit: Sat.String(),
Version: 0,
InputFeePpk: 0,
FinalExpiry: nil,
CreatedAt: 0,
Active: false,
}

generatedKeysets, err := GenerateKeysets(key, GetAmountsForKeysets(), seed)
if err != nil {
t.Errorf("could not generate keyset %+v", err)
}

if len(generatedKeysets) != len(GetAmountsForKeysets()) {
t.Errorf("keyset length is not the same as PosibleKeysetValues length")
}

// check if the keyset amount is 0
if generatedKeysets[0].Amount != 1 {
t.Errorf("keyset amount is not 0")
}
if generatedKeysets[0].Unit != Sat.String() {
t.Errorf("keyset unit is not Sat")
}

if hex.EncodeToString(generatedKeysets[0].PrivKey.PubKey().SerializeCompressed()) != "03fbf65684a42313691fe562aa315f26409a19aaaaa8ef0163fc8d8598f16fe003" {
t.Errorf("keyset id PrivKEy is not correct. %+v", hex.EncodeToString(generatedKeysets[0].PrivKey.PubKey().SerializeCompressed()))
}
justPubkeys := []*secp256k1.PublicKey{}

for i := range generatedKeysets {
justPubkeys = append(justPubkeys, generatedKeysets[i].GetPubKey())
}

keysetId, err := DeriveKeysetId(justPubkeys)

if err != nil {
t.Errorf("could not derive keyset id %+v", err)
}

if keysetId != "0014d74f728e80b8" {
t.Errorf("keyset id is not correct")
}
}

func TestChangeProofsStateToPending(t *testing.T) {

proofs := Proofs{
Proof{
Amount: 1,
State: PROOF_UNSPENT,
C: WrappedPublicKey{PublicKey: nil},
Y: WrappedPublicKey{PublicKey: nil},
Quote: nil,
Id: "",
Secret: "",
Witness: "",
SeenAt: 0,
},
Proof{
Amount: 2,
State: PROOF_UNSPENT,
C: WrappedPublicKey{PublicKey: nil},
Y: WrappedPublicKey{PublicKey: nil},
Quote: nil,
Id: "",
Secret: "",
Witness: "",
SeenAt: 0,
},
}
proofs.SetProofsState(PROOF_PENDING)

if proofs[0].State != PROOF_PENDING {
t.Errorf("proof transformation not working, should be: %v ", proofs[1].State)
}
if proofs[1].State != PROOF_PENDING {
t.Errorf("proof transformation not working, should be: %v ", proofs[1].State)

}

}
func TestChangeProofsStateToPendingAndQuoteSet(t *testing.T) {

proofs := Proofs{
Proof{
Amount: 1,
State: PROOF_UNSPENT,
C: WrappedPublicKey{PublicKey: nil},
Y: WrappedPublicKey{PublicKey: nil},
Quote: nil,
Id: "",
Secret: "",
Witness: "",
SeenAt: 0,
},
Proof{
Amount: 2,
State: PROOF_UNSPENT,
C: WrappedPublicKey{PublicKey: nil},
Y: WrappedPublicKey{PublicKey: nil},
Quote: nil,
Id: "",
Secret: "",
Witness: "",
SeenAt: 0,
},
}
proofs.SetPendingAndQuoteRef("123")

if proofs[0].State != PROOF_PENDING {
t.Errorf("proof transformation not working, should be: %v ", proofs[1].State)
}
res := "123"
if *proofs[0].Quote != res {
t.Errorf("proof transformation not working, should be: %v. is: ", "123")
}
if proofs[1].State != PROOF_PENDING {
t.Errorf("proof transformation not working, should be: %v ", proofs[1].State)

}
if *proofs[1].Quote != res {
t.Errorf("proof transformation not working, should be: %v ", "123")
}

}

// V2 Generation keysets
func TestKeysetIdGenerationV2Vector1(t *testing.T) {
keysStringMap := map[string]string{
"1": "03a40f20667ed53513075dc51e715ff2046cad64eb68960632269ba7f0210e38bc",
Expand Down Expand Up @@ -192,7 +54,6 @@ func TestKeysetIdGenerationV2Vector1(t *testing.T) {
}
}

// V2 Generation keysets
func TestKeysetIdGenerationV2Vector2(t *testing.T) {
keysStringMap := map[string]string{
"1": "03ba786a2c0745f8c30e490288acd7a72dd53d65afd292ddefa326a4a3fa14c566",
Expand Down Expand Up @@ -297,7 +158,6 @@ func TestKeysetIdGenerationV2Vector2(t *testing.T) {
}
}

// V2 Generation keysets
func TestKeysetIdGenerationV2Vector3(t *testing.T) {
keysStringMap := map[string]string{
"1": "03ba786a2c0745f8c30e490288acd7a72dd53d65afd292ddefa326a4a3fa14c566",
Expand Down
77 changes: 77 additions & 0 deletions api/cashu/proofs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,83 @@ import (
"testing"
)

func TestChangeProofsStateToPending(t *testing.T) {
proofs := Proofs{
Proof{
Amount: 1,
State: PROOF_UNSPENT,
C: WrappedPublicKey{PublicKey: nil},
Y: WrappedPublicKey{PublicKey: nil},
Quote: nil,
Id: "",
Secret: "",
Witness: "",
SeenAt: 0,
},
Proof{
Amount: 2,
State: PROOF_UNSPENT,
C: WrappedPublicKey{PublicKey: nil},
Y: WrappedPublicKey{PublicKey: nil},
Quote: nil,
Id: "",
Secret: "",
Witness: "",
SeenAt: 0,
},
}
proofs.SetProofsState(PROOF_PENDING)

if proofs[0].State != PROOF_PENDING {
t.Errorf("proof transformation not working, should be: %v ", proofs[1].State)
}
if proofs[1].State != PROOF_PENDING {
t.Errorf("proof transformation not working, should be: %v ", proofs[1].State)
}
}

func TestChangeProofsStateToPendingAndQuoteSet(t *testing.T) {
proofs := Proofs{
Proof{
Amount: 1,
State: PROOF_UNSPENT,
C: WrappedPublicKey{PublicKey: nil},
Y: WrappedPublicKey{PublicKey: nil},
Quote: nil,
Id: "",
Secret: "",
Witness: "",
SeenAt: 0,
},
Proof{
Amount: 2,
State: PROOF_UNSPENT,
C: WrappedPublicKey{PublicKey: nil},
Y: WrappedPublicKey{PublicKey: nil},
Quote: nil,
Id: "",
Secret: "",
Witness: "",
SeenAt: 0,
},
}
proofs.SetPendingAndQuoteRef("123")

if proofs[0].State != PROOF_PENDING {
t.Errorf("proof transformation not working, should be: %v ", proofs[1].State)
}
res := "123"
if *proofs[0].Quote != res {
t.Errorf("proof transformation not working, should be: %v. is: ", "123")
}
if proofs[1].State != PROOF_PENDING {
t.Errorf("proof transformation not working, should be: %v ", proofs[1].State)
}
if *proofs[1].Quote != res {
t.Errorf("proof transformation not working, should be: %v ", "123")
}
}

// NOTE: NUT-11 SIG_INPUTS Test Vectors

func TestCheckP2PKProof(t *testing.T) {
Expand Down
Loading