feature/refactor did state (#10)

* feat(did): remove account types

* feat: Refactor Property to Proof in zkprop.go

* feat: add ZKP proof mechanism for verifications

* fix: return bool and error from pinInitialVault

* feat: implement KeyshareSet for managing user and validator keyshares

* feat: Update Credential type in protobuf

* feat: update credential schema with sign count

* feat: migrate  and  modules to middleware

* refactor: rename vault module to ORM

* chore(dwn): add service worker registration to index template

* feat: integrate service worker for offline functionality

* refactor(did): use DIDNamespace enum for verification method in proto reflection

* refactor: update protobuf definitions to support Keyshare

* feat: expose did keeper in app keepers

* Add Motr Web App

* refactor: rename motr/handlers/discovery.go to motr/handlers/openid.go

* refactor: move session related code to middleware

* feat: add database operations for managing assets, chains, and credentials

* feat: add htmx support for UI updates

* refactor: extract common helper scripts

* chore: remove unused storage GUI components

* refactor: Move frontend rendering to dedicated handlers

* refactor: rename  to

* refactor: move alert implementation to templ

* feat: add alert component with icon, title, and message

* feat: add new RequestHeaders struct to store request headers

* Feature/create home view (#9)

* refactor: move view logic to new htmx handler

* refactor: remove unnecessary dependencies

* refactor: remove unused dependencies

* feat(devbox): integrate air for local development

* feat: implement openid connect discovery document

* refactor: rename  to

* refactor(did): update service handling to support DNS discovery

* feat: add support for user and validator keyshares

* refactor: move keyshare signing logic to signer
This commit is contained in:
Prad Nukala
2024-09-11 15:10:54 -04:00
committed by GitHub
parent 4f2d342649
commit bbfe2a2329
197 changed files with 14668 additions and 27810 deletions
+157
View File
@@ -1,12 +1,19 @@
package types
import (
"crypto/sha256"
"encoding/hex"
fmt "fmt"
"github.com/cosmos/btcutil/bech32"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
"github.com/mr-tron/base58/base58"
"github.com/onsonr/crypto"
// this line is used by starport scaffolding # 1
)
@@ -41,3 +48,153 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}
type ChainCode uint32
const (
ChainCodeBTC ChainCode = 0
ChainCodeETH ChainCode = 60
ChainCodeIBC ChainCode = 118
ChainCodeSNR ChainCode = 703
)
var InitialChainCodes = map[DIDNamespace]ChainCode{
DIDNamespace_DID_NAMESPACE_BITCOIN: ChainCodeBTC,
DIDNamespace_DID_NAMESPACE_IBC: ChainCodeIBC,
DIDNamespace_DID_NAMESPACE_ETHEREUM: ChainCodeETH,
DIDNamespace_DID_NAMESPACE_SONR: ChainCodeSNR,
}
func (c ChainCode) FormatAddress(pubKey *PubKey) (string, error) {
switch c {
case ChainCodeBTC:
return bech32.Encode("bc", pubKey.Bytes())
case ChainCodeETH:
return bech32.Encode("eth", pubKey.Bytes())
case ChainCodeSNR:
return bech32.Encode("idx", pubKey.Bytes())
case ChainCodeIBC:
return bech32.Encode("cosmos", pubKey.Bytes())
}
return "", ErrUnsopportedChainCode
}
func (n DIDNamespace) ChainCode() (uint32, error) {
switch n {
case DIDNamespace_DID_NAMESPACE_BITCOIN:
return 0, nil
case DIDNamespace_DID_NAMESPACE_ETHEREUM:
return 64, nil
case DIDNamespace_DID_NAMESPACE_IBC:
return 118, nil
case DIDNamespace_DID_NAMESPACE_SONR:
return 703, nil
default:
return 0, fmt.Errorf("unsupported chain")
}
}
func (n DIDNamespace) DIDMethod() string {
switch n {
case DIDNamespace_DID_NAMESPACE_IPFS:
return "ipfs"
case DIDNamespace_DID_NAMESPACE_SONR:
return "sonr"
case DIDNamespace_DID_NAMESPACE_BITCOIN:
return "btcr"
case DIDNamespace_DID_NAMESPACE_ETHEREUM:
return "ethr"
case DIDNamespace_DID_NAMESPACE_IBC:
return "ibcr"
case DIDNamespace_DID_NAMESPACE_WEBAUTHN:
return "webauthn"
case DIDNamespace_DID_NAMESPACE_DWN:
return "motr"
case DIDNamespace_DID_NAMESPACE_SERVICE:
return "web"
default:
return "n/a"
}
}
func (n DIDNamespace) FormatDID(subject string) string {
return fmt.Sprintf("%s:%s", n.DIDMethod(), subject)
}
type EncodedKey []byte
func (e KeyEncoding) EncodeRaw(data []byte) (EncodedKey, error) {
switch e {
case KeyEncoding_KEY_ENCODING_RAW:
return data, nil
case KeyEncoding_KEY_ENCODING_HEX:
return []byte(hex.EncodeToString(data)), nil
case KeyEncoding_KEY_ENCODING_MULTIBASE:
return []byte(base58.Encode(data)), nil
default:
return nil, nil
}
}
func (e KeyEncoding) DecodeRaw(data EncodedKey) ([]byte, error) {
switch e {
case KeyEncoding_KEY_ENCODING_RAW:
return data, nil
case KeyEncoding_KEY_ENCODING_HEX:
return hex.DecodeString(string(data))
case KeyEncoding_KEY_ENCODING_MULTIBASE:
return base58.Decode(string(data))
default:
return nil, nil
}
}
type COSEAlgorithmIdentifier int
func (k KeyAlgorithm) CoseIdentifier() COSEAlgorithmIdentifier {
switch k {
case KeyAlgorithm_KEY_ALGORITHM_ES256:
return COSEAlgorithmIdentifier(-7)
case KeyAlgorithm_KEY_ALGORITHM_ES384:
return COSEAlgorithmIdentifier(-35)
case KeyAlgorithm_KEY_ALGORITHM_ES512:
return COSEAlgorithmIdentifier(-36)
case KeyAlgorithm_KEY_ALGORITHM_EDDSA:
return COSEAlgorithmIdentifier(-8)
case KeyAlgorithm_KEY_ALGORITHM_ES256K:
return COSEAlgorithmIdentifier(-10)
default:
return COSEAlgorithmIdentifier(0)
}
}
func (k KeyCurve) ComputePublicKey(data []byte) (*PubKey, error) {
return nil, ErrUnsupportedKeyCurve
}
func (k *Keyshare) Equals(o crypto.MPCShare) bool {
opk := o.GetPublicKey()
if opk != nil && k.PublicKey == nil {
return false
}
return k.GetRole() == o.GetRole()
}
func (k *Keyshare) IsUser() bool {
return k.Role == 2
}
func (k *Keyshare) IsValidator() bool {
return k.Role == 1
}
// ComputeOriginTXTRecord generates a fingerprint for a given origin
func ComputeOriginTXTRecord(origin string) string {
h := sha256.New()
h.Write([]byte(origin))
return fmt.Sprintf("v=sonr,o=%s,p=%x", origin, h.Sum(nil))
}
-136
View File
@@ -1,136 +0,0 @@
package types
import (
"encoding/hex"
fmt "fmt"
"github.com/cosmos/btcutil/bech32"
"github.com/mr-tron/base58/base58"
)
type ChainCode uint32
const (
ChainCodeBTC ChainCode = 0
ChainCodeETH ChainCode = 60
ChainCodeIBC ChainCode = 118
ChainCodeSNR ChainCode = 703
)
var InitialChainCodes = map[DIDNamespace]ChainCode{
DIDNamespace_DID_NAMESPACE_BITCOIN: ChainCodeBTC,
DIDNamespace_DID_NAMESPACE_IBC: ChainCodeIBC,
DIDNamespace_DID_NAMESPACE_ETHEREUM: ChainCodeETH,
DIDNamespace_DID_NAMESPACE_SONR: ChainCodeSNR,
}
func (c ChainCode) FormatAddress(pubKey *PubKey) (string, error) {
switch c {
case ChainCodeBTC:
return bech32.Encode("bc", pubKey.Bytes())
case ChainCodeETH:
return bech32.Encode("eth", pubKey.Bytes())
case ChainCodeSNR:
return bech32.Encode("idx", pubKey.Bytes())
case ChainCodeIBC:
return bech32.Encode("cosmos", pubKey.Bytes())
}
return "", ErrUnsopportedChainCode
}
func (n DIDNamespace) ChainCode() (uint32, error) {
switch n {
case DIDNamespace_DID_NAMESPACE_BITCOIN:
return 0, nil
case DIDNamespace_DID_NAMESPACE_ETHEREUM:
return 64, nil
case DIDNamespace_DID_NAMESPACE_IBC:
return 118, nil
case DIDNamespace_DID_NAMESPACE_SONR:
return 703, nil
default:
return 0, fmt.Errorf("unsupported chain")
}
}
func (n DIDNamespace) DIDMethod() string {
switch n {
case DIDNamespace_DID_NAMESPACE_IPFS:
return "ipfs"
case DIDNamespace_DID_NAMESPACE_SONR:
return "sonr"
case DIDNamespace_DID_NAMESPACE_BITCOIN:
return "btcr"
case DIDNamespace_DID_NAMESPACE_ETHEREUM:
return "ethr"
case DIDNamespace_DID_NAMESPACE_IBC:
return "ibcr"
case DIDNamespace_DID_NAMESPACE_WEBAUTHN:
return "webauthn"
case DIDNamespace_DID_NAMESPACE_DWN:
return "motr"
case DIDNamespace_DID_NAMESPACE_SERVICE:
return "web"
default:
return "n/a"
}
}
func (n DIDNamespace) FormatDID(subject string) string {
return fmt.Sprintf("%s:%s", n.DIDMethod(), subject)
}
type EncodedKey []byte
func (e KeyEncoding) EncodeRaw(data []byte) (EncodedKey, error) {
switch e {
case KeyEncoding_KEY_ENCODING_RAW:
return data, nil
case KeyEncoding_KEY_ENCODING_HEX:
return []byte(hex.EncodeToString(data)), nil
case KeyEncoding_KEY_ENCODING_MULTIBASE:
return []byte(base58.Encode(data)), nil
default:
return nil, nil
}
}
func (e KeyEncoding) DecodeRaw(data EncodedKey) ([]byte, error) {
switch e {
case KeyEncoding_KEY_ENCODING_RAW:
return data, nil
case KeyEncoding_KEY_ENCODING_HEX:
return hex.DecodeString(string(data))
case KeyEncoding_KEY_ENCODING_MULTIBASE:
return base58.Decode(string(data))
default:
return nil, nil
}
}
type COSEAlgorithmIdentifier int
func (k KeyAlgorithm) CoseIdentifier() COSEAlgorithmIdentifier {
switch k {
case KeyAlgorithm_KEY_ALGORITHM_ES256:
return COSEAlgorithmIdentifier(-7)
case KeyAlgorithm_KEY_ALGORITHM_ES384:
return COSEAlgorithmIdentifier(-35)
case KeyAlgorithm_KEY_ALGORITHM_ES512:
return COSEAlgorithmIdentifier(-36)
case KeyAlgorithm_KEY_ALGORITHM_EDDSA:
return COSEAlgorithmIdentifier(-8)
case KeyAlgorithm_KEY_ALGORITHM_ES256K:
return COSEAlgorithmIdentifier(-10)
default:
return COSEAlgorithmIdentifier(0)
}
}
func (k KeyCurve) ComputePublicKey(data []byte) (*PubKey, error) {
return nil, ErrUnsupportedKeyCurve
}
+2
View File
@@ -7,9 +7,11 @@ var (
ErrInvalidETHAddressFormat = sdkerrors.Register(ModuleName, 200, "invalid ETH address format")
ErrInvalidBTCAddressFormat = sdkerrors.Register(ModuleName, 201, "invalid BTC address format")
ErrInvalidIDXAddressFormat = sdkerrors.Register(ModuleName, 202, "invalid IDX address format")
ErrInvalidOriginFormat = sdkerrors.Register(ModuleName, 203, "invalid origin format")
ErrInvalidServiceOrigin = sdkerrors.Register(ModuleName, 300, "invalid service origin")
ErrUnrecognizedService = sdkerrors.Register(ModuleName, 301, "unrecognized service")
ErrUnsupportedKeyEncoding = sdkerrors.Register(ModuleName, 400, "unsupported key encoding")
ErrUnsopportedChainCode = sdkerrors.Register(ModuleName, 401, "unsupported chain code")
ErrUnsupportedKeyCurve = sdkerrors.Register(ModuleName, 402, "unsupported key curve")
ErrInvalidSignature = sdkerrors.Register(ModuleName, 403, "invalid signature")
)
+36 -16
View File
@@ -53,7 +53,6 @@ func DefaultParams() Params {
WhitelistedAssets: DefaultAssets(),
WhitelistedChains: DefaultChains(),
AllowedPublicKeys: DefaultKeyInfos(),
OpenidConfig: DefaultOpenIDConfig(),
LocalhostRegistrationEnabled: true,
ConveyancePreference: "direct",
AttestationFormats: []string{"packed", "android-key", "fido-u2f", "apple"},
@@ -163,21 +162,6 @@ func DefaultKeyInfos() []*KeyInfo {
}
}
func DefaultOpenIDConfig() *OpenIDConfig {
return &OpenIDConfig{
Issuer: "https://sonr.id",
AuthorizationEndpoint: "https://api.sonr.id/auth",
TokenEndpoint: "https://api.sonr.id/token",
UserinfoEndpoint: "https://api.sonr.id/userinfo",
ScopesSupported: []string{"openid", "profile", "email", "web3", "sonr"},
ResponseTypesSupported: []string{"code"},
ResponseModesSupported: []string{"query", "form_post"},
GrantTypesSupported: []string{"authorization_code", "refresh_token"},
AcrValuesSupported: []string{"passkey"},
SubjectTypesSupported: []string{"public"},
}
}
func (p Params) ActiveParams(ipfsActive bool) Params {
p.IpfsActive = ipfsActive
return p
@@ -198,3 +182,39 @@ func (p Params) Validate() error {
// TODO:
return nil
}
//
// # Genesis Structures
//
// Equal returns true if two asset infos are equal
func (a *AssetInfo) Equal(b *AssetInfo) bool {
if a == nil && b == nil {
return true
}
return false
}
// Equal returns true if two chain infos are equal
func (c *ChainInfo) Equal(b *ChainInfo) bool {
if c == nil && b == nil {
return true
}
return false
}
// Equal returns true if two key infos are equal
func (k *KeyInfo) Equal(b *KeyInfo) bool {
if k == nil && b == nil {
return true
}
return false
}
// Equal returns true if two validator infos are equal
func (v *ValidatorInfo) Equal(b *ValidatorInfo) bool {
if v == nil && b == nil {
return true
}
return false
}
+161 -861
View File
File diff suppressed because it is too large Load Diff
-137
View File
@@ -1,137 +0,0 @@
package types
import (
"encoding/hex"
"github.com/mr-tron/base58/base58"
)
//
// # Genesis Structures
//
// Equal returns true if two asset infos are equal
func (a *AssetInfo) Equal(b *AssetInfo) bool {
if a == nil && b == nil {
return true
}
return false
}
// Equal returns true if two chain infos are equal
func (c *ChainInfo) Equal(b *ChainInfo) bool {
if c == nil && b == nil {
return true
}
return false
}
// Equal returns true if two OpenID config infos are equal
func (o *OpenIDConfig) Equal(b *OpenIDConfig) bool {
if o == nil && b == nil {
return true
}
return false
}
// Equal returns true if two key infos are equal
func (k *KeyInfo) Equal(b *KeyInfo) bool {
if k == nil && b == nil {
return true
}
return false
}
// Equal returns true if two validator infos are equal
func (v *ValidatorInfo) Equal(b *ValidatorInfo) bool {
if v == nil && b == nil {
return true
}
return false
}
// DecodePublicKey extracts the public key from the given data
func (k *KeyInfo) DecodePublicKey(data interface{}) ([]byte, error) {
var bz []byte
switch v := data.(type) {
case string:
bz = []byte(v)
case []byte:
bz = v
default:
return nil, ErrUnsupportedKeyEncoding
}
if k.Encoding == KeyEncoding_KEY_ENCODING_RAW {
return bz, nil
}
if k.Encoding == KeyEncoding_KEY_ENCODING_HEX {
return hex.DecodeString(string(bz))
}
if k.Encoding == KeyEncoding_KEY_ENCODING_MULTIBASE {
return base58.Decode(string(bz))
}
return nil, ErrUnsupportedKeyEncoding
}
// EncodePublicKey encodes the public key according to the KeyInfo's encoding
func (k *KeyInfo) EncodePublicKey(data []byte) (string, error) {
if k.Encoding == KeyEncoding_KEY_ENCODING_RAW {
return string(data), nil
}
if k.Encoding == KeyEncoding_KEY_ENCODING_HEX {
return hex.EncodeToString(data), nil
}
if k.Encoding == KeyEncoding_KEY_ENCODING_MULTIBASE {
return base58.Encode(data), nil
}
return "", ErrUnsupportedKeyEncoding
}
// DiscoveryDocument represents the OIDC discovery document.
type DiscoveryDocument struct {
Issuer string `json:"issuer"`
AuthorizationEndpoint string `json:"authorization_endpoint"`
TokenEndpoint string `json:"token_endpoint"`
UserinfoEndpoint string `json:"userinfo_endpoint"`
JwksURI string `json:"jwks_uri"`
RegistrationEndpoint string `json:"registration_endpoint"`
ScopesSupported []string `json:"scopes_supported"`
ResponseTypesSupported []string `json:"response_types_supported"`
SubjectTypesSupported []string `json:"subject_types_supported"`
IDTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported"`
ClaimsSupported []string `json:"claims_supported"`
GrantTypesSupported []string `json:"grant_types_supported"`
TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported"`
}
var WalletKeyInfo = &KeyInfo{
Role: KeyRole_KEY_ROLE_DELEGATION,
Curve: KeyCurve_KEY_CURVE_SECP256K1,
Algorithm: KeyAlgorithm_KEY_ALGORITHM_ECDSA,
Encoding: KeyEncoding_KEY_ENCODING_HEX,
Type: KeyType_KEY_TYPE_BIP32,
}
var EthKeyInfo = &KeyInfo{
Role: KeyRole_KEY_ROLE_DELEGATION,
Curve: KeyCurve_KEY_CURVE_KECCAK256,
Algorithm: KeyAlgorithm_KEY_ALGORITHM_ECDSA,
Encoding: KeyEncoding_KEY_ENCODING_HEX,
Type: KeyType_KEY_TYPE_BIP32,
}
var SonrKeyInfo = &KeyInfo{
Role: KeyRole_KEY_ROLE_INVOCATION,
Curve: KeyCurve_KEY_CURVE_P256,
Algorithm: KeyAlgorithm_KEY_ALGORITHM_ECDSA,
Encoding: KeyEncoding_KEY_ENCODING_HEX,
Type: KeyType_KEY_TYPE_MPC,
}
var ChainCodeKeyInfos = map[ChainCode]*KeyInfo{
ChainCodeBTC: WalletKeyInfo,
ChainCodeETH: EthKeyInfo,
ChainCodeSNR: SonrKeyInfo,
ChainCodeIBC: WalletKeyInfo,
}
+2135 -2682
View File
File diff suppressed because it is too large Load Diff
+68 -41
View File
@@ -1,15 +1,44 @@
package types
import (
fmt "fmt"
"math/big"
"encoding/hex"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/onsonr/crypto/core/curves"
"github.com/onsonr/crypto/signatures/ecdsa"
"golang.org/x/crypto/sha3"
"github.com/mr-tron/base58/base58"
"github.com/onsonr/crypto"
)
var WalletKeyInfo = &KeyInfo{
Role: KeyRole_KEY_ROLE_DELEGATION,
Curve: KeyCurve_KEY_CURVE_SECP256K1,
Algorithm: KeyAlgorithm_KEY_ALGORITHM_ECDSA,
Encoding: KeyEncoding_KEY_ENCODING_HEX,
Type: KeyType_KEY_TYPE_BIP32,
}
var EthKeyInfo = &KeyInfo{
Role: KeyRole_KEY_ROLE_DELEGATION,
Curve: KeyCurve_KEY_CURVE_KECCAK256,
Algorithm: KeyAlgorithm_KEY_ALGORITHM_ECDSA,
Encoding: KeyEncoding_KEY_ENCODING_HEX,
Type: KeyType_KEY_TYPE_BIP32,
}
var SonrKeyInfo = &KeyInfo{
Role: KeyRole_KEY_ROLE_INVOCATION,
Curve: KeyCurve_KEY_CURVE_P256,
Algorithm: KeyAlgorithm_KEY_ALGORITHM_ECDSA,
Encoding: KeyEncoding_KEY_ENCODING_HEX,
Type: KeyType_KEY_TYPE_MPC,
}
var ChainCodeKeyInfos = map[ChainCode]*KeyInfo{
ChainCodeBTC: WalletKeyInfo,
ChainCodeETH: EthKeyInfo,
ChainCodeSNR: SonrKeyInfo,
ChainCodeIBC: WalletKeyInfo,
}
// NewEthPublicKey returns a new ethereum public key
func NewPublicKey(data []byte, keyInfo *KeyInfo) (*PubKey, error) {
encKey, err := keyInfo.Encoding.EncodeRaw(data)
@@ -52,21 +81,12 @@ func (k *PubKey) Clone() cryptotypes.PubKey {
// VerifySignature verifies a signature over the given message
func (k *PubKey) VerifySignature(msg []byte, sig []byte) bool {
pp, err := buildEcPoint(k.Bytes())
pk, err := crypto.ComputeEcdsaPublicKey(k.Bytes())
sigMpc, err := crypto.DeserializeMPCSignature(sig)
if err != nil {
return false
}
sigEd, err := ecdsa.DeserializeSecp256k1Signature(sig)
if err != nil {
return false
}
hash := sha3.New256()
_, err = hash.Write(msg)
if err != nil {
return false
}
digest := hash.Sum(nil)
return curves.VerifyEcdsa(pp, digest[:], sigEd)
return crypto.VerifyMPCSignature(sigMpc, msg, pk)
}
// Equals returns true if two public keys are equal
@@ -79,36 +99,43 @@ func (k *PubKey) Equals(k2 cryptotypes.PubKey) bool {
// Type returns the type of the public key
func (k *PubKey) Type() string {
return ""
return k.KeyType.String()
}
// VerifySignature verifies the signature of a message
func VerifySignature(key []byte, msg []byte, sig []byte) bool {
pp, err := buildEcPoint(key)
if err != nil {
return false
// DecodePublicKey extracts the public key from the given data
func (k *KeyInfo) DecodePublicKey(data interface{}) ([]byte, error) {
var bz []byte
switch v := data.(type) {
case string:
bz = []byte(v)
case []byte:
bz = v
default:
return nil, ErrUnsupportedKeyEncoding
}
sigEd, err := ecdsa.DeserializeSecp256k1Signature(sig)
if err != nil {
return false
if k.Encoding == KeyEncoding_KEY_ENCODING_RAW {
return bz, nil
}
hash := sha3.New256()
_, err = hash.Write(msg)
if err != nil {
return false
if k.Encoding == KeyEncoding_KEY_ENCODING_HEX {
return hex.DecodeString(string(bz))
}
digest := hash.Sum(nil)
return curves.VerifyEcdsa(pp, digest[:], sigEd)
if k.Encoding == KeyEncoding_KEY_ENCODING_MULTIBASE {
return base58.Decode(string(bz))
}
return nil, ErrUnsupportedKeyEncoding
}
// BuildEcPoint builds an elliptic curve point from a compressed byte slice
func buildEcPoint(pubKey []byte) (*curves.EcPoint, error) {
crv := curves.K256()
x := new(big.Int).SetBytes(pubKey[1:33])
y := new(big.Int).SetBytes(pubKey[33:])
ecCurve, err := crv.ToEllipticCurve()
if err != nil {
return nil, fmt.Errorf("error converting curve: %v", err)
// EncodePublicKey encodes the public key according to the KeyInfo's encoding
func (k *KeyInfo) EncodePublicKey(data []byte) (string, error) {
if k.Encoding == KeyEncoding_KEY_ENCODING_RAW {
return string(data), nil
}
return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil
if k.Encoding == KeyEncoding_KEY_ENCODING_HEX {
return hex.EncodeToString(data), nil
}
if k.Encoding == KeyEncoding_KEY_ENCODING_MULTIBASE {
return base58.Encode(data), nil
}
return "", ErrUnsupportedKeyEncoding
}
+72 -1597
View File
File diff suppressed because it is too large Load Diff
-28
View File
@@ -1,28 +0,0 @@
package types
import didv1 "github.com/onsonr/sonr/api/did/v1"
func (m *MsgRegisterService) ExtractServiceRecord() (*didv1.ServiceRecord, error) {
return &didv1.ServiceRecord{
Controller: m.Controller,
OriginUri: m.OriginUri,
Description: m.Description,
Permissions: convertPermissions(m.GetScopes()),
}, nil
}
func convertPermissions(permissions *Permissions) *didv1.Permissions {
if permissions == nil {
return nil
}
return &didv1.Permissions{}
}
// UserInfo represents the user information.
type UserInfo struct {
DID string `json:"did"`
Sub string `json:"sub"`
Name string `json:"name"`
Email string `json:"email"`
// Add other claims as needed
}
-12
View File
@@ -1,12 +0,0 @@
package types
// ByteArray is a list of byte arrays
type ByteArray = [][]byte
// ToVerificationMethod converts a Profile to a VerificationMethod
func (p Profile) ToVerificationMethod() VerificationMethod {
return VerificationMethod{
Id: p.Id,
Controller: p.Controller,
}
}
+736 -957
View File
File diff suppressed because it is too large Load Diff
+346 -752
View File
File diff suppressed because it is too large Load Diff
-66
View File
@@ -1,66 +0,0 @@
package types
import (
"crypto/hmac"
"crypto/sha512"
"encoding/binary"
"errors"
"math/big"
"github.com/btcsuite/btcd/btcec/v2"
)
// ComputeAccountPublicKey computes the public key of a child key given the extended public key, chain code, and index.
func ComputeAccountPublicKey(extPubKey []byte, chainCode uint32, index int) ([]byte, error) {
// Check if the index is a hardened child key
if chainCode&0x80000000 != 0 && index < 0 {
return nil, errors.New("invalid index")
}
// Serialize the public key
pubKey, err := btcec.ParsePubKey(extPubKey)
if err != nil {
return nil, err
}
pubKeyBytes := pubKey.SerializeCompressed()
// Serialize the index
indexBytes := make([]byte, 4)
binary.BigEndian.PutUint32(indexBytes, uint32(index))
// Compute the HMAC-SHA512
mac := hmac.New(sha512.New, []byte{byte(chainCode)})
mac.Write(pubKeyBytes)
mac.Write(indexBytes)
I := mac.Sum(nil)
// Split I into two 32-byte sequences
IL := I[:32]
// Convert IL to a big integer
ilNum := new(big.Int).SetBytes(IL)
// Check if parse256(IL) >= n
curve := btcec.S256()
if ilNum.Cmp(curve.N) >= 0 {
return nil, errors.New("invalid child key")
}
// Compute the child public key
ilx, ily := curve.ScalarBaseMult(IL)
childX, childY := curve.Add(ilx, ily, pubKey.X(), pubKey.Y())
lx := newBigIntFieldVal(childX)
ly := newBigIntFieldVal(childY)
// Create the child public key
childPubKey := btcec.NewPublicKey(lx, ly)
childPubKeyBytes := childPubKey.SerializeCompressed()
return childPubKeyBytes, nil
}
// newBigIntFieldVal creates a new field value from a big integer.
func newBigIntFieldVal(val *big.Int) *btcec.FieldVal {
lx := new(btcec.FieldVal)
lx.SetByteSlice(val.Bytes())
return lx
}
+44 -31
View File
@@ -7,12 +7,18 @@ import (
"github.com/onsonr/crypto/core/curves"
)
// Accumulator is the accumulator for the ZKP
type Accumulator []byte
// Element is the element for the BLS scheme
type Element = accumulator.Element
// NewProperty creates a new Property which is used for ZKP
func NewProperty(propertyKey string, pubKey []byte) (*Property, error) {
input := append(pubKey, []byte(propertyKey)...)
// Witness is the witness for the ZKP
type Witness []byte
// NewProof creates a new Proof which is used for ZKP
func NewProof(id, controller, issuer, property string, pubKey []byte) (*Proof, error) {
input := append(pubKey, []byte(property)...)
hash := []byte(input)
curve := curves.BLS12381(&curves.PointBls12381G1{})
@@ -26,47 +32,54 @@ func NewProperty(propertyKey string, pubKey []byte) (*Property, error) {
return nil, fmt.Errorf("failed to marshal secret key: %w", err)
}
return &Property{Key: keyBytes}, nil
return &Proof{
Id: id,
Controller: controller,
Issuer: issuer,
Property: property,
Accumulator: keyBytes,
}, nil
}
// CreateAccumulator creates a new accumulator
func CreateAccumulator(prop *Property, values ...string) (*Accumulator, error) {
// CreateAccumulator creates a new accumulator for a Proof
func CreateAccumulator(proof *Proof, values ...string) error {
curve := curves.BLS12381(&curves.PointBls12381G1{})
acc, err := new(accumulator.Accumulator).New(curve)
if err != nil {
return nil, err
return err
}
secretKey := new(accumulator.SecretKey)
if err := secretKey.UnmarshalBinary(prop.Key); err != nil {
return nil, err
if err := secretKey.UnmarshalBinary(proof.Accumulator); err != nil {
return err
}
fin, _, err := acc.Update(secretKey, ConvertValuesToZeroKnowledgeElements(values), nil)
if err != nil {
return nil, err
return err
}
accBytes, err := fin.MarshalBinary()
if err != nil {
return nil, fmt.Errorf("failed to marshal accumulator: %w", err)
return fmt.Errorf("failed to marshal accumulator: %w", err)
}
return &Accumulator{Accumulator: accBytes}, nil
proof.Accumulator = accBytes
return nil
}
// CreateWitness creates a witness for the accumulator for a given value
func CreateWitness(prop *Property, acc *Accumulator, value string) (*Witness, error) {
// CreateWitness creates a witness for the accumulator in a Proof for a given value
func CreateWitness(proof *Proof, value string) ([]byte, error) {
curve := curves.BLS12381(&curves.PointBls12381G1{})
element := curve.Scalar.Hash([]byte(value))
secretKey := new(accumulator.SecretKey)
if err := secretKey.UnmarshalBinary(prop.Key); err != nil {
if err := secretKey.UnmarshalBinary(proof.Accumulator); err != nil {
return nil, err
}
accObj := new(accumulator.Accumulator)
if err := accObj.UnmarshalBinary(acc.Accumulator); err != nil {
if err := accObj.UnmarshalBinary(proof.Accumulator); err != nil {
return nil, fmt.Errorf("failed to unmarshal accumulator: %w", err)
}
@@ -79,14 +92,13 @@ func CreateWitness(prop *Property, acc *Accumulator, value string) (*Witness, er
if err != nil {
return nil, fmt.Errorf("failed to marshal witness: %w", err)
}
return &Witness{Witness: witnessBytes}, nil
return witnessBytes, nil
}
// VerifyWitness proves that a value is a member of the accumulator
func VerifyWitness(prop *Property, acc *Accumulator, witness *Witness) error {
func VerifyWitness(proof *Proof, acc Accumulator, witness Witness) error {
secretKey := new(accumulator.SecretKey)
if err := secretKey.UnmarshalBinary(prop.Key); err != nil {
if err := secretKey.UnmarshalBinary([]byte(proof.Id)); err != nil {
return err
}
@@ -97,41 +109,42 @@ func VerifyWitness(prop *Property, acc *Accumulator, witness *Witness) error {
}
accObj := new(accumulator.Accumulator)
if err := accObj.UnmarshalBinary(acc.Accumulator); err != nil {
if err := accObj.UnmarshalBinary(proof.Accumulator); err != nil {
return fmt.Errorf("failed to unmarshal accumulator: %w", err)
}
witnessObj := new(accumulator.MembershipWitness)
if err := witnessObj.UnmarshalBinary(witness.Witness); err != nil {
if err := witnessObj.UnmarshalBinary(witness); err != nil {
return fmt.Errorf("failed to unmarshal witness: %w", err)
}
return witnessObj.Verify(publicKey, accObj)
}
// UpdateAccumulator updates the accumulator with new values
func UpdateAccumulator(prop *Property, acc *Accumulator, addValues []string, removeValues []string) (*Accumulator, error) {
// UpdateAccumulator updates the accumulator in a Proof with new values
func UpdateAccumulator(proof *Proof, addValues []string, removeValues []string) error {
secretKey := new(accumulator.SecretKey)
if err := secretKey.UnmarshalBinary(prop.Key); err != nil {
return nil, err
if err := secretKey.UnmarshalBinary(proof.Accumulator); err != nil {
return err
}
accObj := new(accumulator.Accumulator)
if err := accObj.UnmarshalBinary(acc.Accumulator); err != nil {
return nil, fmt.Errorf("failed to unmarshal accumulator: %w", err)
if err := accObj.UnmarshalBinary(proof.Accumulator); err != nil {
return fmt.Errorf("failed to unmarshal accumulator: %w", err)
}
updatedAcc, _, err := accObj.Update(secretKey, ConvertValuesToZeroKnowledgeElements(addValues), ConvertValuesToZeroKnowledgeElements(removeValues))
if err != nil {
return nil, err
return err
}
updatedAccBytes, err := updatedAcc.MarshalBinary()
if err != nil {
return nil, fmt.Errorf("failed to marshal updated accumulator: %w", err)
return fmt.Errorf("failed to marshal updated accumulator: %w", err)
}
return &Accumulator{Accumulator: updatedAccBytes}, nil
proof.Accumulator = updatedAccBytes
return nil
}
// ConvertValuesToZeroKnowledgeElements converts a slice of strings to a slice of accumulator elements