-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #35 from piavgh/feature/verify-zklogin-signature
feat: verify zklogin signature
- Loading branch information
Showing
14 changed files
with
673 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package scheme | ||
|
||
type SignatureScheme string | ||
|
||
const ( | ||
ED25519 SignatureScheme = "ED25519" | ||
Secp256k1 SignatureScheme = "Secp256k1" | ||
Secp256r1 SignatureScheme = "Secp256r1" | ||
MultiSig SignatureScheme = "MultiSig" | ||
ZkLogin SignatureScheme = "ZkLogin" | ||
) | ||
|
||
var SignatureSchemeToSize = map[SignatureScheme]int{ | ||
ED25519: 32, | ||
Secp256k1: 33, | ||
Secp256r1: 33, | ||
} | ||
|
||
var SignatureSchemeToFlag = map[SignatureScheme]byte{ | ||
ED25519: 0x00, | ||
Secp256k1: 0x01, | ||
Secp256r1: 0x02, | ||
MultiSig: 0x03, | ||
ZkLogin: 0x05, | ||
} | ||
|
||
var SignatureFlagToScheme = map[byte]SignatureScheme{ | ||
0x00: ED25519, | ||
0x01: Secp256k1, | ||
0x02: Secp256r1, | ||
0x03: MultiSig, | ||
0x05: ZkLogin, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package cryptography | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/block-vision/sui-go-sdk/cryptography/scheme" | ||
"github.com/block-vision/sui-go-sdk/mystenbcs" | ||
"github.com/block-vision/sui-go-sdk/zklogin" | ||
) | ||
|
||
type SignaturePubkeyPair struct { | ||
SignatureScheme scheme.SignatureScheme | ||
Signature []byte | ||
PubKey []byte | ||
} | ||
|
||
func parseSerializedSignature(serializedSignature string) (*SignaturePubkeyPair, error) { | ||
if strings.EqualFold(serializedSignature, "") { | ||
return nil, fmt.Errorf("multiSig is not supported") | ||
} | ||
|
||
bytes, err := mystenbcs.FromBase64(serializedSignature) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
signatureScheme, ok := scheme.SignatureFlagToScheme[bytes[0]] | ||
if !ok { | ||
return nil, fmt.Errorf("signature flag is not supported") | ||
} | ||
|
||
switch signatureScheme { | ||
case "ZkLogin": | ||
parsedSerializedZkLoginSignature, err := zklogin.ParseSerializedZkLoginSignature(serializedSignature) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &SignaturePubkeyPair{ | ||
SignatureScheme: parsedSerializedZkLoginSignature.SignatureScheme, | ||
Signature: parsedSerializedZkLoginSignature.Signature, | ||
PubKey: parsedSerializedZkLoginSignature.PubKey, | ||
}, nil | ||
case "ED25519": | ||
fallthrough | ||
case "Secp256k1": | ||
fallthrough | ||
case "Secp256r1": | ||
size, ok := scheme.SignatureSchemeToSize[signatureScheme] | ||
if !ok { | ||
return nil, fmt.Errorf("signature scheme is not supported") | ||
} | ||
|
||
signature := bytes[1 : len(bytes)-size] | ||
pubKeyBytes := bytes[1+len(signature):] | ||
|
||
keyPair := &SignaturePubkeyPair{ | ||
SignatureScheme: signatureScheme, | ||
Signature: signature, | ||
PubKey: pubKeyBytes, | ||
} | ||
|
||
return keyPair, nil | ||
default: | ||
return nil, fmt.Errorf("signature scheme is not supported") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package ed25519 | ||
|
||
import ( | ||
"crypto/ed25519" | ||
"encoding/base64" | ||
"encoding/hex" | ||
"fmt" | ||
|
||
"github.com/machinebox/graphql" | ||
"golang.org/x/crypto/blake2b" | ||
|
||
"github.com/block-vision/sui-go-sdk/constant" | ||
) | ||
|
||
type Ed25519PublicKey struct { | ||
signature []byte | ||
} | ||
|
||
func NewEd25519PublicKey(signature []byte) *Ed25519PublicKey { | ||
return &Ed25519PublicKey{ | ||
signature: signature, | ||
} | ||
} | ||
|
||
func (e *Ed25519PublicKey) ToSuiAddress() string { | ||
return "" | ||
} | ||
|
||
func (e *Ed25519PublicKey) VerifyPersonalMessage(message []byte, signature []byte, client *graphql.Client) (bool, error) { | ||
b64Message := base64.StdEncoding.EncodeToString([]byte(message)) | ||
return VerifyMessage(b64Message, signature, constant.PersonalMessageIntentScope) | ||
} | ||
|
||
func VerifyMessage(message, signature string, scope constant.IntentScope) (signer string, pass bool, err error) { | ||
b64Bytes, _ := base64.StdEncoding.DecodeString(message) | ||
messageBytes := NewMessageWithIntent(b64Bytes, scope) | ||
|
||
serializedSignature, err := FromSerializedSignature(signature) | ||
if err != nil { | ||
return "", false, err | ||
} | ||
digest := blake2b.Sum256(messageBytes) | ||
|
||
pass = ed25519.Verify(serializedSignature.PubKey[:], digest[:], serializedSignature.Signature) | ||
|
||
signer = Ed25519PublicKeyToSuiAddress(serializedSignature.PubKey) | ||
if err != nil { | ||
return "", false, fmt.Errorf("invalid signer %v", err) | ||
} | ||
|
||
return | ||
} | ||
|
||
func Ed25519PublicKeyToSuiAddress(pubKey []byte) string { | ||
newPubkey := []byte{byte(SigFlagEd25519)} | ||
newPubkey = append(newPubkey, pubKey...) | ||
|
||
addrBytes := blake2b.Sum256(newPubkey) | ||
return fmt.Sprintf("0x%s", hex.EncodeToString(addrBytes[:])[:64]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package mystenbcs | ||
|
||
import "encoding/base64" | ||
|
||
func FromBase64(base64String string) ([]byte, error) { | ||
bytes, err := base64.StdEncoding.DecodeString(base64String) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return bytes, nil | ||
} | ||
|
||
func ToBase64(bytes []byte) string { | ||
return base64.StdEncoding.EncodeToString(bytes) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package verify | ||
|
||
import "github.com/machinebox/graphql" | ||
|
||
type IPublicKey interface { | ||
ToSuiAddress() string | ||
VerifyPersonalMessage(message []byte, signature []byte, client *graphql.Client) (bool, error) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package verify | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/block-vision/sui-go-sdk/cryptography" | ||
"github.com/block-vision/sui-go-sdk/cryptography/scheme" | ||
"github.com/block-vision/sui-go-sdk/keypairs/ed25519" | ||
"github.com/block-vision/sui-go-sdk/zklogin" | ||
) | ||
|
||
func VerifyPersonalMessageSignature(message []byte, signature []byte, options *zklogin.ZkLoginPublicIdentifierOptions) (signer string, pass bool, err error) { | ||
parsedSignature := parseSignature(signature, options) | ||
|
||
publicKey, err := publicKeyFromRawBytes(parsedSignature.SignatureScheme, parsedSignature.PubKey, options) | ||
if err != nil { | ||
return "", false, err | ||
} | ||
|
||
pass, err = publicKey.VerifyPersonalMessage(message, parsedSignature.Signature, options.Client) | ||
if err != nil { | ||
return "", false, err | ||
} | ||
|
||
address := publicKey.ToSuiAddress() | ||
|
||
return address, true, nil | ||
} | ||
|
||
func parseSignature(signature []byte, options *zklogin.ZkLoginPublicIdentifierOptions) *cryptography.SignaturePubkeyPair { | ||
return nil | ||
} | ||
|
||
// publicKeyFromRawBytes function in Go | ||
func publicKeyFromRawBytes(signatureScheme scheme.SignatureScheme, bytes []byte, options *zklogin.ZkLoginPublicIdentifierOptions) (IPublicKey, error) { | ||
switch signatureScheme { | ||
case scheme.ED25519: | ||
return ed25519.NewEd25519PublicKey(bytes), nil | ||
case scheme.ZkLogin: | ||
return zklogin.NewZkLoginPublicIdentifier(bytes, options), nil | ||
default: | ||
return nil, errors.New(fmt.Sprintf("Unsupported signature scheme %s", signatureScheme)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package zklogin | ||
|
||
type ProofPoints struct { | ||
A []string `bcs:"a"` | ||
B [][]string `bcs:"b"` | ||
C []string `bcs:"c"` | ||
} | ||
|
||
type IssBase64Details struct { | ||
Value string `bcs:"value"` | ||
IndexMod4 uint8 `bcs:"indexMod4"` | ||
} | ||
|
||
type ZkLoginSignatureInputs struct { | ||
ProofPoints ProofPoints `bcs:"proofPoints"` | ||
IssBase64Details IssBase64Details `bcs:"issBase64Details"` | ||
HeaderBase64 string `bcs:"headerBase64"` | ||
AddressSeed string `bcs:"addressSeed"` | ||
} | ||
|
||
type ZkLoginSignature struct { | ||
Inputs ZkLoginSignatureInputs `bcs:"inputs"` | ||
MaxEpoch uint64 `bcs:"maxEpoch"` | ||
UserSignature []byte `bcs:"userSignature"` | ||
Iss string `bcs:"iss"` | ||
AddressSeed string `bcs:"addressSeed"` | ||
} |
Oops, something went wrong.