Compare commits
109 Commits
proof-chec
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fbb8568c0 | |||
| 36717a0826 | |||
| fe8b5a6e4c | |||
| 4c1ae3a0be | |||
| 1f69e9c2c4 | |||
| 4895a069dd | |||
| ec4cc024d4 | |||
| 0c35addf65 | |||
| c5b594dd69 | |||
| b23a6de775 | |||
| 499f83fd6f | |||
| d660445190 | |||
| 869e449383 | |||
| 6b9698c1e8 | |||
| 33841ea261 | |||
|
|
4b99c9f1df | ||
|
|
39694340cd | ||
|
|
e93e464977 | ||
|
|
823af27272 | ||
|
|
70f039a654 | ||
|
|
d56db6722c | ||
|
|
0647e4ff8a | ||
|
|
06f478b9c3 | ||
|
|
4aedc4de39 | ||
|
|
0fd71612d3 | ||
|
|
29ccdb700e | ||
|
|
2d031fdbdb | ||
|
|
1c4a0a9c81 | ||
|
|
df6dfee210 | ||
|
|
c670433335 | ||
|
|
55f38fef4a | ||
|
|
1098a834fb | ||
|
|
b95e525cfb | ||
|
|
cc207aa202 | ||
|
|
41d679dfab | ||
|
|
cc661f3936 | ||
|
|
07d2745966 | ||
|
|
cd9ee535ad | ||
|
|
9e062b0cc7 | ||
|
|
cf3eb1b3f7 | ||
|
|
3b6d70f47a | ||
|
|
09c8815755 | ||
|
|
f18ae547ab | ||
|
|
ad02aa8d4f | ||
|
|
9c8e9f17fa | ||
|
|
11b4352063 | ||
|
|
b0783bf4a4 | ||
|
|
2eeaaccc6d | ||
|
|
1187674a24 | ||
|
|
4c08b22c61 | ||
|
|
174bf01c64 | ||
|
|
4167bf44bd | ||
|
|
4f4331b677 | ||
|
|
547416e60d | ||
|
|
6c1602507b | ||
|
|
6f4853cd2f | ||
|
|
4c25456583 | ||
|
|
83f3e4c3b0 | ||
|
|
1178e51b18 | ||
|
|
3ec8f56412 | ||
|
|
5891bdcd5d | ||
|
|
6fb25481ce | ||
|
|
e7edccdd71 | ||
|
|
33e8a8a821 | ||
|
|
947add66c5 | ||
|
|
3faf9d598c | ||
|
|
fbf55e98ba | ||
|
|
05c2573d95 | ||
|
|
d7472621ce | ||
|
|
7b44f480ee | ||
|
|
5eb7b1a8e4 | ||
|
|
e91afe29d8 | ||
|
|
a82bce556f | ||
|
|
a54d66afe5 | ||
|
|
14a57d7391 | ||
|
|
68469db91a | ||
|
|
cc1d68be0c | ||
|
|
6d3846ac62 | ||
|
|
6aa33b1547 | ||
|
|
9589cc8b44 | ||
|
|
879c0ab03b | ||
|
|
fe14765c8d | ||
|
|
1b28cb49bf | ||
|
|
e1fc838caf | ||
|
|
f29b9e94fc | ||
|
|
506ed21b94 | ||
|
|
126177b9e5 | ||
|
|
2bddab8b0c | ||
|
|
45ead12131 | ||
|
|
9d5e170409 | ||
|
|
9d047f038d | ||
|
|
4c5afcb084 | ||
|
|
e218b49577 | ||
|
|
4c81ac778e | ||
|
|
7ae65e7c8e | ||
|
|
7f9cb6426c | ||
|
|
9c141029c3 | ||
|
|
0c6717cfbc | ||
|
|
6d7fd28324 | ||
|
|
ccc0120e78 | ||
|
|
bf27b97a57 | ||
|
|
10dd4fa6d1 | ||
|
|
5695609f8b | ||
|
|
b7ddead7c8 | ||
|
|
9cbec37685 | ||
|
|
00dbd975b1 | ||
|
|
c792a4cce5 | ||
|
|
8f3f1c775e | ||
|
|
704ed25768 |
20
.github/Repo.toml
vendored
Normal file
20
.github/Repo.toml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[scopes]
|
||||||
|
ci = [".github/workflows"]
|
||||||
|
config = [".github", "go.mod", "go.sum"]
|
||||||
|
docs = ["Readme.md", "LICENSE.md"]
|
||||||
|
assets = ["assets"]
|
||||||
|
pkg = ["pkg"]
|
||||||
|
args = ["pkg/args"]
|
||||||
|
command = ["pkg/command"]
|
||||||
|
container = ["pkg/container"]
|
||||||
|
meta = ["pkg/meta"]
|
||||||
|
policy = ["pkg/policy"]
|
||||||
|
secretbox = ["pkg/secretbox"]
|
||||||
|
token = ["token"]
|
||||||
|
delegation = ["token/delegation"]
|
||||||
|
invocation = ["token/invocation"]
|
||||||
|
toolkit = ["toolkit"]
|
||||||
|
examples = ["toolkit/_example"]
|
||||||
|
client = ["toolkit/client"]
|
||||||
|
issuer = ["toolkit/issuer"]
|
||||||
|
server = ["toolkit/server"]
|
||||||
21
Readme.md
21
Readme.md
@@ -1,5 +1,5 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://github.com/ucan-wg/go-ucan" target="_blank">
|
<a href="https://code.sonr.org/go/ucan" target="_blank">
|
||||||
<img src="https://raw.githubusercontent.com/ucan-wg/go-ucan/v1/assets/logo.png" alt="go-ucan Logo" height="250"></img>
|
<img src="https://raw.githubusercontent.com/ucan-wg/go-ucan/v1/assets/logo.png" alt="go-ucan Logo" height="250"></img>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@@ -7,19 +7,19 @@
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
<img src="https://img.shields.io/badge/UCAN-v1.0.0--rc.1-blue" alt="UCAN v1.0.0-rc.1">
|
<img src="https://img.shields.io/badge/UCAN-v1.0.0--rc.1-blue" alt="UCAN v1.0.0-rc.1">
|
||||||
<a href="https://github.com/ucan-wg/go-ucan/tags">
|
<a href="https://code.sonr.org/go/ucan/tags">
|
||||||
<img alt="GitHub Tag" src="https://img.shields.io/github/v/tag/ucan-wg/go-ucan">
|
<img alt="GitHub Tag" src="https://img.shields.io/github/v/tag/ucan-wg/go-ucan">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/ucan-wg/go-ucan/actions?query=">
|
<a href="https://code.sonr.org/go/ucan/actions?query=">
|
||||||
<img src="https://github.com/ucan-wg/go-ucan/actions/workflows/gotest.yml/badge.svg" alt="Build Status">
|
<img src="https://code.sonr.org/go/ucan/actions/workflows/gotest.yml/badge.svg" alt="Build Status">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://ucan-wg.github.io/go-ucan/dev/bench/">
|
<a href="https://ucan-wg.github.io/go-ucan/dev/bench/">
|
||||||
<img alt="Go benchmarks" src="https://img.shields.io/badge/Benchmarks-go-blue">
|
<img alt="Go benchmarks" src="https://img.shields.io/badge/Benchmarks-go-blue">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/ucan-wg/go-ucan/blob/v1/LICENSE.md">
|
<a href="https://code.sonr.org/go/ucan/blob/v1/LICENSE.md">
|
||||||
<img alt="Apache 2.0 + MIT License" src="https://img.shields.io/badge/License-Apache--2.0+MIT-green">
|
<img alt="Apache 2.0 OR MIT License" src="https://img.shields.io/badge/License-Apache--2.0_OR_MIT-green">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://pkg.go.dev/github.com/ucan-wg/go-ucan">
|
<a href="https://pkg.go.dev/code.sonr.org/go/ucan">
|
||||||
<img src="https://img.shields.io/badge/Docs-godoc-blue" alt="Docs">
|
<img src="https://img.shields.io/badge/Docs-godoc-blue" alt="Docs">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/JSyFG6XgVM">
|
<a href="https://discord.gg/JSyFG6XgVM">
|
||||||
@@ -41,6 +41,7 @@ The UCAN specification is separated in multiple sub-spec:
|
|||||||
- [Main specification](https://github.com/ucan-wg/spec)
|
- [Main specification](https://github.com/ucan-wg/spec)
|
||||||
- [Delegation](https://github.com/ucan-wg/delegation/tree/v1_ipld)
|
- [Delegation](https://github.com/ucan-wg/delegation/tree/v1_ipld)
|
||||||
- [Invocation](https://github.com/ucan-wg/invocation)
|
- [Invocation](https://github.com/ucan-wg/invocation)
|
||||||
|
- [Container](https://github.com/ucan-wg/container)
|
||||||
|
|
||||||
Not implemented yet:
|
Not implemented yet:
|
||||||
- [Revocation](https://github.com/ucan-wg/revocation/tree/first-draft)
|
- [Revocation](https://github.com/ucan-wg/revocation/tree/first-draft)
|
||||||
@@ -53,11 +54,9 @@ Not implemented yet:
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
`go-ucan` currently support the required parts of the UCAN specification: the main specification, delegation and invocation.
|
`go-ucan` currently support the required parts of the UCAN specification: the main specification, delegation and invocation. It leverages the sibling project [`go-did-it`](https://code.sonr.org/go/did-it) for easy and extensible DID support.
|
||||||
|
|
||||||
Besides that, `go-ucan` also includes:
|
Besides that, `go-ucan` also includes:
|
||||||
- a simplified [DID](https://www.w3.org/TR/did-core/) and [did-key](https://w3c-ccg.github.io/did-method-key/) implementation
|
|
||||||
- a [token container](https://github.com/ucan-wg/go-ucan/tree/v1/pkg/container) with CBOR and CAR format, to package and carry tokens together
|
|
||||||
- support for encrypted values in token's metadata
|
- support for encrypted values in token's metadata
|
||||||
|
|
||||||
## Getting Help
|
## Getting Help
|
||||||
@@ -74,4 +73,4 @@ Artwork by [Bruno Monts](https://www.instagram.com/bruno_monts). Thank you [Rene
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the double license [Apache 2.0 + MIT](https://github.com/ucan-wg/go-ucan/blob/v1/LICENSE.md).
|
This project is licensed under the dual license [Apache 2.0 OR MIT](https://code.sonr.org/go/ucan/blob/v1/LICENSE.md).
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
## did
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
The test suite for this package includes test vectors provided by the
|
|
||||||
authors of the [`did:key` method specification](https://w3c-ccg.github.io/did-method-key/).
|
|
||||||
Some of these tests provide the public key associated with a `did:key`
|
|
||||||
as JWKs and an extra (test-only) dependency has been added to unmarshal
|
|
||||||
the JWK into a Go `struct`. Support for the `secp256k1` encryption
|
|
||||||
algorithm is experimental (but stable in my experience) and requires the
|
|
||||||
addition of the following build tag to properly run:
|
|
||||||
|
|
||||||
```
|
|
||||||
// go:build jwx_es256k
|
|
||||||
```
|
|
||||||
|
|
||||||
WARNING: These tests will not run by default!
|
|
||||||
|
|
||||||
To include these tests from the CLI, execute the following command:
|
|
||||||
|
|
||||||
```
|
|
||||||
go test -v ./did -tags jwx_es256k
|
|
||||||
```
|
|
||||||
|
|
||||||
It should also be possible to configure your IDE to run these tests. For
|
|
||||||
instance, in Codium, add the following JSON snippet to your local project
|
|
||||||
configuration:
|
|
||||||
|
|
||||||
```
|
|
||||||
"go.testTags": "jwx_es256k",
|
|
||||||
```
|
|
||||||
231
did/crypto.go
231
did/crypto.go
@@ -1,231 +0,0 @@
|
|||||||
package did
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
|
||||||
crypto "github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto/pb"
|
|
||||||
"github.com/multiformats/go-multicodec"
|
|
||||||
"github.com/multiformats/go-varint"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GenerateEd25519 generates an Ed25519 private key and the matching DID.
|
|
||||||
// This is the RECOMMENDED algorithm.
|
|
||||||
func GenerateEd25519() (crypto.PrivKey, DID, error) {
|
|
||||||
priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, Undef, nil
|
|
||||||
}
|
|
||||||
did, err := FromPubKey(pub)
|
|
||||||
return priv, did, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateRSA generates a RSA private key and the matching DID.
|
|
||||||
func GenerateRSA() (crypto.PrivKey, DID, error) {
|
|
||||||
// NIST Special Publication 800-57 Part 1 Revision 5
|
|
||||||
// Section 5.6.1.1 (Table 2)
|
|
||||||
// Paraphrased: 2048-bit RSA keys are secure until 2030 and 3072-bit keys are recommended for longer-term security.
|
|
||||||
const keyLength = 3072
|
|
||||||
|
|
||||||
priv, pub, err := crypto.GenerateRSAKeyPair(keyLength, rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, Undef, nil
|
|
||||||
}
|
|
||||||
did, err := FromPubKey(pub)
|
|
||||||
return priv, did, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateEd25519 generates a Secp256k1 private key and the matching DID.
|
|
||||||
func GenerateSecp256k1() (crypto.PrivKey, DID, error) {
|
|
||||||
priv, pub, err := crypto.GenerateSecp256k1Key(rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, Undef, nil
|
|
||||||
}
|
|
||||||
did, err := FromPubKey(pub)
|
|
||||||
return priv, did, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateECDSA generates an ECDSA private key and the matching DID
|
|
||||||
// for the default P256 curve.
|
|
||||||
func GenerateECDSA() (crypto.PrivKey, DID, error) {
|
|
||||||
return GenerateECDSAWithCurve(P256)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateECDSAWithCurve generates an ECDSA private key and matching
|
|
||||||
// DID for the user-supplied curve
|
|
||||||
func GenerateECDSAWithCurve(code multicodec.Code) (crypto.PrivKey, DID, error) {
|
|
||||||
var curve elliptic.Curve
|
|
||||||
|
|
||||||
switch code {
|
|
||||||
case P256:
|
|
||||||
curve = elliptic.P256()
|
|
||||||
case P384:
|
|
||||||
curve = elliptic.P384()
|
|
||||||
case P521:
|
|
||||||
curve = elliptic.P521()
|
|
||||||
default:
|
|
||||||
return nil, Undef, errors.New("unsupported ECDSA curve")
|
|
||||||
}
|
|
||||||
|
|
||||||
priv, pub, err := crypto.GenerateECDSAKeyPairWithCurve(curve, rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
did, err := FromPubKey(pub)
|
|
||||||
|
|
||||||
return priv, did, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromPrivKey is a convenience function that returns the DID associated
|
|
||||||
// with the public key associated with the provided private key.
|
|
||||||
func FromPrivKey(privKey crypto.PrivKey) (DID, error) {
|
|
||||||
return FromPubKey(privKey.GetPublic())
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromPubKey returns a did:key constructed from the provided public key.
|
|
||||||
func FromPubKey(pubKey crypto.PubKey) (DID, error) {
|
|
||||||
var code multicodec.Code
|
|
||||||
|
|
||||||
switch pubKey.Type() {
|
|
||||||
case pb.KeyType_Ed25519:
|
|
||||||
code = multicodec.Ed25519Pub
|
|
||||||
case pb.KeyType_RSA:
|
|
||||||
code = RSA
|
|
||||||
case pb.KeyType_Secp256k1:
|
|
||||||
code = Secp256k1
|
|
||||||
case pb.KeyType_ECDSA:
|
|
||||||
var err error
|
|
||||||
if code, err = codeForCurve(pubKey); err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return Undef, errors.New("unsupported key type")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pubKey.Type() == pb.KeyType_ECDSA && code == Secp256k1 {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
pubKey, err = coerceECDSAToSecp256k1(pubKey)
|
|
||||||
if err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var bytes []byte
|
|
||||||
|
|
||||||
switch pubKey.Type() {
|
|
||||||
case pb.KeyType_ECDSA:
|
|
||||||
pkix, err := pubKey.Raw()
|
|
||||||
if err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
publicKey, err := x509.ParsePKIXPublicKey(pkix)
|
|
||||||
if err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ecdsaPublicKey := publicKey.(*ecdsa.PublicKey)
|
|
||||||
|
|
||||||
bytes = elliptic.MarshalCompressed(ecdsaPublicKey.Curve, ecdsaPublicKey.X, ecdsaPublicKey.Y)
|
|
||||||
case pb.KeyType_Ed25519, pb.KeyType_Secp256k1:
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if bytes, err = pubKey.Raw(); err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
case pb.KeyType_RSA:
|
|
||||||
var err error
|
|
||||||
|
|
||||||
pkix, err := pubKey.Raw()
|
|
||||||
if err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
publicKey, err := x509.ParsePKIXPublicKey(pkix)
|
|
||||||
if err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = x509.MarshalPKCS1PublicKey(publicKey.(*rsa.PublicKey))
|
|
||||||
}
|
|
||||||
|
|
||||||
return DID{
|
|
||||||
code: code,
|
|
||||||
bytes: string(append(varint.ToUvarint(uint64(code)), bytes...)),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToPubKey returns the crypto.PubKey encapsulated in the DID formed by
|
|
||||||
// parsing the provided string.
|
|
||||||
func ToPubKey(s string) (crypto.PubKey, error) {
|
|
||||||
id, err := Parse(s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return id.PubKey()
|
|
||||||
}
|
|
||||||
|
|
||||||
func codeForCurve(pubKey crypto.PubKey) (multicodec.Code, error) {
|
|
||||||
stdPub, err := crypto.PubKeyToStdKey(pubKey)
|
|
||||||
if err != nil {
|
|
||||||
return multicodec.Identity, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ecdsaPub, ok := stdPub.(*ecdsa.PublicKey)
|
|
||||||
if !ok {
|
|
||||||
return multicodec.Identity, errors.New("failed to assert type for code to curve")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ecdsaPub.Curve {
|
|
||||||
case elliptic.P256():
|
|
||||||
return P256, nil
|
|
||||||
case elliptic.P384():
|
|
||||||
return P384, nil
|
|
||||||
case elliptic.P521():
|
|
||||||
return P521, nil
|
|
||||||
case secp256k1.S256():
|
|
||||||
return Secp256k1, nil
|
|
||||||
default:
|
|
||||||
return multicodec.Identity, fmt.Errorf("unsupported ECDSA curve: %s", ecdsaPub.Curve.Params().Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// secp256k1.S256 is a valid ECDSA curve, but the go-libp2p/core/crypto
|
|
||||||
// package treats it as a different type and has a different format for
|
|
||||||
// the raw bytes of the public key.
|
|
||||||
//
|
|
||||||
// If a valid ECDSA public key was created using the secp256k1.S256 curve,
|
|
||||||
// this function will "convert" it from a crypto.ECDSAPubKey to a
|
|
||||||
// crypto.Secp256k1PublicKey.
|
|
||||||
func coerceECDSAToSecp256k1(pubKey crypto.PubKey) (crypto.PubKey, error) {
|
|
||||||
stdPub, err := crypto.PubKeyToStdKey(pubKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ecdsaPub, ok := stdPub.(*ecdsa.PublicKey)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("failed to assert type for secp256k1 coersion")
|
|
||||||
}
|
|
||||||
|
|
||||||
ecdsaPubBytes := append([]byte{0x04}, append(ecdsaPub.X.Bytes(), ecdsaPub.Y.Bytes()...)...)
|
|
||||||
|
|
||||||
secp256k1Pub, err := secp256k1.ParsePubKey(ecdsaPubBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cryptoPub := crypto.Secp256k1PublicKey(*secp256k1Pub)
|
|
||||||
|
|
||||||
return &cryptoPub, nil
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
package did_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rand"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto/pb"
|
|
||||||
"github.com/multiformats/go-multicodec"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
exampleDIDStr = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
|
|
||||||
examplePubKeyStr = "Lm/M42cB3HkUiODQsXRcweM6TByfzEHGO9ND274JcOY="
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestFromPubKey(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
_, ecdsaP256, err := crypto.GenerateECDSAKeyPairWithCurve(elliptic.P256(), rand.Reader)
|
|
||||||
require.NoError(t, err)
|
|
||||||
_, ecdsaP384, err := crypto.GenerateECDSAKeyPairWithCurve(elliptic.P384(), rand.Reader)
|
|
||||||
require.NoError(t, err)
|
|
||||||
_, ecdsaP521, err := crypto.GenerateECDSAKeyPairWithCurve(elliptic.P521(), rand.Reader)
|
|
||||||
require.NoError(t, err)
|
|
||||||
_, ecdsaSecp256k1, err := crypto.GenerateECDSAKeyPairWithCurve(secp256k1.S256(), rand.Reader)
|
|
||||||
require.NoError(t, err)
|
|
||||||
_, ed25519, err := crypto.GenerateEd25519Key(rand.Reader)
|
|
||||||
require.NoError(t, err)
|
|
||||||
_, rsa, err := crypto.GenerateRSAKeyPair(2048, rand.Reader)
|
|
||||||
require.NoError(t, err)
|
|
||||||
_, secp256k1PubKey1, err := crypto.GenerateSecp256k1Key(rand.Reader)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
test := func(pub crypto.PubKey, code multicodec.Code) func(t *testing.T) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
return func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
id, err := did.FromPubKey(pub)
|
|
||||||
require.NoError(t, err)
|
|
||||||
p, err := id.PubKey()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, pub, p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("ECDSA with P256 curve", test(ecdsaP256, did.P256))
|
|
||||||
t.Run("ECDSA with P384 curve", test(ecdsaP384, did.P384))
|
|
||||||
t.Run("ECDSA with P521 curve", test(ecdsaP521, did.P521))
|
|
||||||
t.Run("Ed25519", test(ed25519, did.Ed25519))
|
|
||||||
t.Run("RSA", test(rsa, did.RSA))
|
|
||||||
t.Run("secp256k1", test(secp256k1PubKey1, did.Secp256k1))
|
|
||||||
|
|
||||||
t.Run("ECDSA with secp256k1 curve (coerced)", func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
id, err := did.FromPubKey(ecdsaSecp256k1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
p, err := id.PubKey()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, pb.KeyType_Secp256k1, p.Type())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("unmarshaled example key (secp256k1)", func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
id, err := did.FromPubKey(examplePubKey(t))
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, exampleDID(t), id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToPubKey(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
pubKey, err := did.ToPubKey(exampleDIDStr)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, examplePubKey(t), pubKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
func exampleDID(t *testing.T) did.DID {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
id, err := did.Parse(exampleDIDStr)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
func examplePubKey(t *testing.T) crypto.PubKey {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
pubKeyCfg, err := crypto.ConfigDecodeKey(examplePubKeyStr)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
pubKey, err := crypto.UnmarshalEd25519PublicKey(pubKeyCfg)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return pubKey
|
|
||||||
}
|
|
||||||
143
did/did.go
143
did/did.go
@@ -1,143 +0,0 @@
|
|||||||
package did
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/x509"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
crypto "github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
mbase "github.com/multiformats/go-multibase"
|
|
||||||
"github.com/multiformats/go-multicodec"
|
|
||||||
varint "github.com/multiformats/go-varint"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Signature algorithms from the [did:key specification]
|
|
||||||
//
|
|
||||||
// [did:key specification]: https://w3c-ccg.github.io/did-method-key/#signature-method-creation-algorithm
|
|
||||||
const (
|
|
||||||
X25519 = multicodec.X25519Pub
|
|
||||||
Ed25519 = multicodec.Ed25519Pub // UCAN required/recommended
|
|
||||||
P256 = multicodec.P256Pub // UCAN required
|
|
||||||
P384 = multicodec.P384Pub
|
|
||||||
P521 = multicodec.P521Pub
|
|
||||||
Secp256k1 = multicodec.Secp256k1Pub // UCAN required
|
|
||||||
RSA = multicodec.RsaPub
|
|
||||||
)
|
|
||||||
|
|
||||||
// Undef can be used to represent a nil or undefined DID, using DID{}
|
|
||||||
// directly is also acceptable.
|
|
||||||
var Undef = DID{}
|
|
||||||
|
|
||||||
// DID is a Decentralized Identifier of the did:key type, directly holding a cryptographic public key.
|
|
||||||
// [did:key format]: https://w3c-ccg.github.io/did-method-key/
|
|
||||||
type DID struct {
|
|
||||||
code multicodec.Code
|
|
||||||
bytes string // as string instead of []byte to allow the == operator
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse returns the DID from the string representation or an error if
|
|
||||||
// the prefix and method are incorrect, if an unknown encryption algorithm
|
|
||||||
// is specified or if the method-specific-identifier's bytes don't
|
|
||||||
// represent a public key for the specified encryption algorithm.
|
|
||||||
func Parse(str string) (DID, error) {
|
|
||||||
const keyPrefix = "did:key:"
|
|
||||||
|
|
||||||
if !strings.HasPrefix(str, keyPrefix) {
|
|
||||||
return Undef, fmt.Errorf("must start with 'did:key'")
|
|
||||||
}
|
|
||||||
|
|
||||||
baseCodec, bytes, err := mbase.Decode(str[len(keyPrefix):])
|
|
||||||
if err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
if baseCodec != mbase.Base58BTC {
|
|
||||||
return Undef, fmt.Errorf("not Base58BTC encoded")
|
|
||||||
}
|
|
||||||
code, _, err := varint.FromUvarint(bytes)
|
|
||||||
if err != nil {
|
|
||||||
return Undef, err
|
|
||||||
}
|
|
||||||
switch multicodec.Code(code) {
|
|
||||||
case Ed25519, P256, Secp256k1, RSA:
|
|
||||||
return DID{bytes: string(bytes), code: multicodec.Code(code)}, nil
|
|
||||||
default:
|
|
||||||
return Undef, fmt.Errorf("unsupported did:key multicodec: 0x%x", code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustParse is like Parse but panics instead of returning an error.
|
|
||||||
func MustParse(str string) DID {
|
|
||||||
did, err := Parse(str)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return did
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defined tells if the DID is defined, not equal to Undef.
|
|
||||||
func (d DID) Defined() bool {
|
|
||||||
return d.code != 0 || len(d.bytes) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// PubKey returns the public key encapsulated by the did:key.
|
|
||||||
func (d DID) PubKey() (crypto.PubKey, error) {
|
|
||||||
unmarshaler, ok := map[multicodec.Code]crypto.PubKeyUnmarshaller{
|
|
||||||
X25519: crypto.UnmarshalEd25519PublicKey,
|
|
||||||
Ed25519: crypto.UnmarshalEd25519PublicKey,
|
|
||||||
P256: ecdsaPubKeyUnmarshaler(elliptic.P256()),
|
|
||||||
P384: ecdsaPubKeyUnmarshaler(elliptic.P384()),
|
|
||||||
P521: ecdsaPubKeyUnmarshaler(elliptic.P521()),
|
|
||||||
Secp256k1: crypto.UnmarshalSecp256k1PublicKey,
|
|
||||||
RSA: rsaPubKeyUnmarshaller,
|
|
||||||
}[d.code]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unsupported multicodec: %d", d.code)
|
|
||||||
}
|
|
||||||
|
|
||||||
codeSize := varint.UvarintSize(uint64(d.code))
|
|
||||||
return unmarshaler([]byte(d.bytes)[codeSize:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// String formats the decentralized identity document (DID) as a string.
|
|
||||||
func (d DID) String() string {
|
|
||||||
if d == Undef {
|
|
||||||
return "(undefined)"
|
|
||||||
}
|
|
||||||
key, _ := mbase.Encode(mbase.Base58BTC, []byte(d.bytes))
|
|
||||||
return "did:key:" + key
|
|
||||||
}
|
|
||||||
|
|
||||||
func ecdsaPubKeyUnmarshaler(curve elliptic.Curve) crypto.PubKeyUnmarshaller {
|
|
||||||
return func(data []byte) (crypto.PubKey, error) {
|
|
||||||
x, y := elliptic.UnmarshalCompressed(curve, data)
|
|
||||||
|
|
||||||
ecdsaPublicKey := &ecdsa.PublicKey{
|
|
||||||
Curve: curve,
|
|
||||||
X: x,
|
|
||||||
Y: y,
|
|
||||||
}
|
|
||||||
|
|
||||||
pkix, err := x509.MarshalPKIXPublicKey(ecdsaPublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return crypto.UnmarshalECDSAPublicKey(pkix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func rsaPubKeyUnmarshaller(data []byte) (crypto.PubKey, error) {
|
|
||||||
rsaPublicKey, err := x509.ParsePKCS1PublicKey(data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pkix, err := x509.MarshalPKIXPublicKey(rsaPublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return crypto.UnmarshalRsaPublicKey(pkix)
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package did
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseDIDKey(t *testing.T) {
|
|
||||||
str := "did:key:z6Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z"
|
|
||||||
d, err := Parse(str)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, str, d.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMustParseDIDKey(t *testing.T) {
|
|
||||||
str := "did:key:z6Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z"
|
|
||||||
require.NotPanics(t, func() {
|
|
||||||
d := MustParse(str)
|
|
||||||
require.Equal(t, str, d.String())
|
|
||||||
})
|
|
||||||
str = "did:key:z7Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z"
|
|
||||||
require.Panics(t, func() {
|
|
||||||
MustParse(str)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEquivalence(t *testing.T) {
|
|
||||||
undef0 := DID{}
|
|
||||||
undef1 := Undef
|
|
||||||
|
|
||||||
did0, err := Parse("did:key:z6Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z")
|
|
||||||
require.NoError(t, err)
|
|
||||||
did1, err := Parse("did:key:z6Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z")
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.True(t, undef0 == undef1)
|
|
||||||
require.False(t, undef0 == did0)
|
|
||||||
require.True(t, did0 == did1)
|
|
||||||
require.False(t, undef1 == did1)
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
// Package didtest provides Personas that can be used for testing. Each
|
|
||||||
// Persona has a name, crypto.PrivKey and associated crypto.PubKey and
|
|
||||||
// did.DID.
|
|
||||||
package didtest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
alicePrivKeyB64 = "CAESQHdNJLBBiuc1AdwPHBkubB2KS1p0cv2JEF7m8tfwtrcm5ajaYPm+XmVCmtcHOF2lGDlmaiDA7emfwD3IrcyES0M="
|
|
||||||
bobPrivKeyB64 = "CAESQHBz+AIop1g+9iBDj+ufUc/zm9/ry7c6kDFO8Wl/D0+H63V9hC6s9l4npf3pYEFCjBtlR0AMNWMoFQKSlYNKo20="
|
|
||||||
carolPrivKeyB64 = "CAESQPrCgkcHnYFXDT9AlAydhPECBEivEuuVx9dJxLjVvDTmJIVNivfzg6H4mAiPfYS+5ryVVUZTHZBzvMuvvvG/Ks0="
|
|
||||||
danPrivKeyB64 = "CAESQCgNhzofKhC+7hW6x+fNd7iMPtQHeEmKRhhlduf/I7/TeOEFYAEflbJ0sAhMeDJ/HQXaAvsWgHEbJ3ZLhP8q2B0="
|
|
||||||
erinPrivKeyB64 = "CAESQKhCJo5UBpQcthko8DKMFsbdZ+qqQ5oc01CtLCqrE90dF2GfRlrMmot3WPHiHGCmEYi5ZMEHuiSI095e/6O4Bpw="
|
|
||||||
frankPrivKeyB64 = "CAESQDlXPKsy3jHh7OWTWQqyZF95Ueac5DKo7xD0NOBE5F2BNr1ZVxRmJ2dBELbOt8KP9sOACcO9qlCB7uMA1UQc7sk="
|
|
||||||
)
|
|
||||||
|
|
||||||
// Persona is a generic participant used for cryptographic testing.
|
|
||||||
type Persona int
|
|
||||||
|
|
||||||
// The provided Personas were selected from the first few generic
|
|
||||||
// participants listed in this [table].
|
|
||||||
//
|
|
||||||
// [table]: https://en.wikipedia.org/wiki/Alice_and_Bob#Cryptographic_systems
|
|
||||||
const (
|
|
||||||
PersonaAlice Persona = iota
|
|
||||||
PersonaBob
|
|
||||||
PersonaCarol
|
|
||||||
PersonaDan
|
|
||||||
PersonaErin
|
|
||||||
PersonaFrank
|
|
||||||
)
|
|
||||||
|
|
||||||
var privKeys map[Persona]crypto.PrivKey
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
privKeys = make(map[Persona]crypto.PrivKey, 6)
|
|
||||||
for persona, privKeyCfg := range privKeyB64() {
|
|
||||||
privKeyMar, err := crypto.ConfigDecodeKey(privKeyCfg)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
privKey, err := crypto.UnmarshalPrivateKey(privKeyMar)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
privKeys[persona] = privKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DID returns a did.DID based on the Persona's Ed25519 public key.
|
|
||||||
func (p Persona) DID() did.DID {
|
|
||||||
d, err := did.FromPrivKey(p.PrivKey())
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name returns the username of the Persona.
|
|
||||||
func (p Persona) Name() string {
|
|
||||||
name, ok := map[Persona]string{
|
|
||||||
PersonaAlice: "Alice",
|
|
||||||
PersonaBob: "Bob",
|
|
||||||
PersonaCarol: "Carol",
|
|
||||||
PersonaDan: "Dan",
|
|
||||||
PersonaErin: "Erin",
|
|
||||||
PersonaFrank: "Frank",
|
|
||||||
}[p]
|
|
||||||
if !ok {
|
|
||||||
panic(fmt.Sprintf("Unknown persona: %v", p))
|
|
||||||
}
|
|
||||||
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrivKey returns the Ed25519 private key for the Persona.
|
|
||||||
func (p Persona) PrivKey() crypto.PrivKey {
|
|
||||||
res, ok := privKeys[p]
|
|
||||||
if !ok {
|
|
||||||
panic(fmt.Sprintf("Unknown persona: %v", p))
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Persona) PrivKeyConfig() string {
|
|
||||||
res, ok := privKeyB64()[p]
|
|
||||||
if !ok {
|
|
||||||
panic(fmt.Sprintf("Unknown persona: %v", p))
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// PubKey returns the Ed25519 public key for the Persona.
|
|
||||||
func (p Persona) PubKey() crypto.PubKey {
|
|
||||||
return p.PrivKey().GetPublic()
|
|
||||||
}
|
|
||||||
|
|
||||||
// PubKeyConfig returns the marshaled and encoded Ed25519 public key
|
|
||||||
// for the Persona.
|
|
||||||
func (p Persona) PubKeyConfig() string {
|
|
||||||
pubKeyMar, err := crypto.MarshalPublicKey(p.PrivKey().GetPublic())
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return crypto.ConfigEncodeKey(pubKeyMar)
|
|
||||||
}
|
|
||||||
|
|
||||||
func privKeyB64() map[Persona]string {
|
|
||||||
return map[Persona]string{
|
|
||||||
PersonaAlice: alicePrivKeyB64,
|
|
||||||
PersonaBob: bobPrivKeyB64,
|
|
||||||
PersonaCarol: carolPrivKeyB64,
|
|
||||||
PersonaDan: danPrivKeyB64,
|
|
||||||
PersonaErin: erinPrivKeyB64,
|
|
||||||
PersonaFrank: frankPrivKeyB64,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Personas returns an (alphabetically) ordered list of the defined
|
|
||||||
// Persona values.
|
|
||||||
func Personas() []Persona {
|
|
||||||
return []Persona{
|
|
||||||
PersonaAlice,
|
|
||||||
PersonaBob,
|
|
||||||
PersonaCarol,
|
|
||||||
PersonaDan,
|
|
||||||
PersonaErin,
|
|
||||||
PersonaFrank,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DidToName retrieve the persona's name from its DID.
|
|
||||||
func DidToName(d did.DID) string {
|
|
||||||
return map[did.DID]string{
|
|
||||||
PersonaAlice.DID(): "Alice",
|
|
||||||
PersonaBob.DID(): "Bob",
|
|
||||||
PersonaCarol.DID(): "Carol",
|
|
||||||
PersonaDan.DID(): "Dan",
|
|
||||||
PersonaErin.DID(): "Erin",
|
|
||||||
PersonaFrank.DID(): "Frank",
|
|
||||||
}[d]
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
//go:build jwx_es256k
|
|
||||||
|
|
||||||
package did_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did"
|
|
||||||
"github.com/ucan-wg/go-ucan/did/testvectors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestDidKeyVectors executes tests read from the [test vector files] provided
|
|
||||||
// as part of the DID Key method's [specification].
|
|
||||||
//
|
|
||||||
// [test vector files]: https://github.com/w3c-ccg/did-method-key/tree/main/test-vectors
|
|
||||||
// [specification]: https://w3c-ccg.github.io/did-method-key
|
|
||||||
func TestDidKeyVectors(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
for _, f := range []string{
|
|
||||||
// TODO: These test vectors are not supported by go-libp2p/core/crypto
|
|
||||||
// "bls12381.json",
|
|
||||||
"ed25519-x25519.json",
|
|
||||||
"nist-curves.json",
|
|
||||||
"rsa.json",
|
|
||||||
"secp256k1.json",
|
|
||||||
// This test vector only contains a DID Document
|
|
||||||
// "x25519.json",
|
|
||||||
} {
|
|
||||||
vectors := loadTestVectors(t, f)
|
|
||||||
|
|
||||||
t.Run(f, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
for k, vector := range vectors {
|
|
||||||
t.Run(k, func(t *testing.T) {
|
|
||||||
// round-trip pubkey-->did-->pubkey, verified against the test vectors.
|
|
||||||
|
|
||||||
exp := vectorPubKey(t, vector)
|
|
||||||
|
|
||||||
id, err := did.FromPubKey(exp)
|
|
||||||
require.NoError(t, err, f, k)
|
|
||||||
act, err := id.PubKey()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, k, id.String(), f, k)
|
|
||||||
assert.Equal(t, exp, act)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadTestVectors(t *testing.T, filename string) testvectors.Vectors {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
data, err := os.ReadFile(filepath.Join("testvectors", filename))
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
var vs testvectors.Vectors
|
|
||||||
|
|
||||||
require.NoError(t, json.Unmarshal(data, &vs))
|
|
||||||
|
|
||||||
return vs
|
|
||||||
}
|
|
||||||
|
|
||||||
func vectorPubKey(t *testing.T, v testvectors.Vector) crypto.PubKey {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
pubKey, err := v.PubKey()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotZero(t, pubKey)
|
|
||||||
|
|
||||||
return pubKey
|
|
||||||
}
|
|
||||||
@@ -1,231 +0,0 @@
|
|||||||
{
|
|
||||||
"did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY": {
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY",
|
|
||||||
"publicKeyBase58": "25EEkQtcLKsEzQ6JTo9cg4W7NHpaurn4Wg6LaNPFq6JQXnrP91SDviUz7KrJVMJd76CtAZFsRLYzvgX2JGxo2ccUHtuHk7ELCWwrkBDfrXCFVfqJKDootee9iVaF6NpdJtBE",
|
|
||||||
"privateKeyBase58": "8TXrPTbhefHvcz2vkGsDLBZT2UMeemveLKbdh5JZCvvn"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/bls12381-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY#zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY",
|
|
||||||
"publicKeyBase58": "25EEkQtcLKsEzQ6JTo9cg4W7NHpaurn4Wg6LaNPFq6JQXnrP91SDviUz7KrJVMJd76CtAZFsRLYzvgX2JGxo2ccUHtuHk7ELCWwrkBDfrXCFVfqJKDootee9iVaF6NpdJtBE"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY#zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY#zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY#zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY#zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY": {
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY",
|
|
||||||
"publicKeyBase58": "t5QqHdxR4C6QJWJAnk3qVd2DMr4MVFEefdP43i7fLbR5A2qJkE5bqgEtyzpNsDViGEsMKHMdpo7fKbPMhGihbfxz3Dv2Hw36XvprLHBA5DDFSphmy91oHQFdahQMei2HjoE",
|
|
||||||
"privateKeyBase58": "URWBZN9g2ZfKVdAz1L8pvVwEBqCbGBozt4p8Cootb35"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/bls12381-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY#zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY",
|
|
||||||
"publicKeyBase58": "t5QqHdxR4C6QJWJAnk3qVd2DMr4MVFEefdP43i7fLbR5A2qJkE5bqgEtyzpNsDViGEsMKHMdpo7fKbPMhGihbfxz3Dv2Hw36XvprLHBA5DDFSphmy91oHQFdahQMei2HjoE"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY#zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY#zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY#zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY#zUC77uxiMKceQoxciSy1xgk3nvP8c8NZXDnaY1xsXZaU5UmsZdnwStUke8Ca8zAdPX3MQTHEMhDTCgfdGU7UrY4RRdVhqZp8FaAaoaXFEVp2ZAM7oj3P45BuTCfc3t9FEGBAEQY"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW": {
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW",
|
|
||||||
"publicKeyBase58": "25VFRgQEfbJ3Pit6Z3mnZbKPK9BdQYGwdmfdcmderjYZ12BFNQYeowjMN1AYKKKcacF3UH35ZNpBqCR8y8QLeeaGLL7UKdKLcFje3VQnosesDNHsU8jBvtvYmLJusxXsSUBC",
|
|
||||||
"privateKeyBase58": "48FTGTBBhezV7Ldk5g392NSxP2hwgEgWiSZQkMoNri7E"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/bls12381-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW#zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW",
|
|
||||||
"publicKeyBase58": "25VFRgQEfbJ3Pit6Z3mnZbKPK9BdQYGwdmfdcmderjYZ12BFNQYeowjMN1AYKKKcacF3UH35ZNpBqCR8y8QLeeaGLL7UKdKLcFje3VQnosesDNHsU8jBvtvYmLJusxXsSUBC"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW#zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW#zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW#zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW#zUC7KKoJk5ttwuuc8pmQDiUmtckEPTwcaFVZe4DSFV7fURuoRnD17D3xkBK3A9tZqdADkTTMKSwNkhjo9Hs6HfgNUXo48TNRaxU6XPLSPdRgMc15jCD5DfN34ixjoVemY62JxnW"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU": {
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU",
|
|
||||||
"publicKeyBase58": "21LWABB5R6mqxvcU6LWMMt9yCAVyt8C1mHREs1EAX23fLcAEPMK4dWx59Jd6RpJ5geGt881vH9yPzZyC8WpHhS2g296mumPxJA3Aghp9jMoACE13rtTie8FYdgzgUw24eboA",
|
|
||||||
"privateKeyBase58": "86rp8w6Q7zgDdKqYxZsdTyhZogzwbcR7wf3VQrhV3xLG"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/bls12381-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU#zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU",
|
|
||||||
"publicKeyBase58": "21LWABB5R6mqxvcU6LWMMt9yCAVyt8C1mHREs1EAX23fLcAEPMK4dWx59Jd6RpJ5geGt881vH9yPzZyC8WpHhS2g296mumPxJA3Aghp9jMoACE13rtTie8FYdgzgUw24eboA"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU#zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU#zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU#zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU#zUC7FB43ErjeTPiBLZ8wWT3aBTL7QnJ6AAZh9opgV5dKkw291mC23yTnKQ2pTcSgLbdKnVJ1ARn6XrwxWqvFg5dRFzCjwSg1j35nRgs5c2nbqkJ4auPTyPtkJ3xcABRNWaDX6QU"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA": {
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA",
|
|
||||||
"publicKeyBase58": "21XhJ3o4ZSgDgRoyP4Pp8agXMwLycuRa1U6fM4ZzJBxH3gJEQbiuwP3Qh2zNoofNrBKPqp3FgXxGvW84cFwMD29oA7Q9w3L8Sjcc3e9mZqFgs8iWxSsDNRcbQdoYtGaxu11r",
|
|
||||||
"privateKeyBase58": "5LjJ3yibKGP4zKbNgqeiQ284g8LJYnbF7ZBve7Ke9qZ5"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/bls12381-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA#zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA",
|
|
||||||
"type": "Bls12381G2Key2020",
|
|
||||||
"controller": "did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA",
|
|
||||||
"publicKeyBase58": "21XhJ3o4ZSgDgRoyP4Pp8agXMwLycuRa1U6fM4ZzJBxH3gJEQbiuwP3Qh2zNoofNrBKPqp3FgXxGvW84cFwMD29oA7Q9w3L8Sjcc3e9mZqFgs8iWxSsDNRcbQdoYtGaxu11r"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA#zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA#zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA#zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA#zUC7FNFB7UinoJ5tqkeEELWLsytHBdHpwQ7wLVFAYRT6vqdr5uC3JPK6BVNNByj4KxvVKXoirT7VuqptSznjRCgvr7Ksuk42zyFw1GJSYNQSKCpjVcrZXoPUbR1P6zHmr97mVdA"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk": {
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk#z3tEEysHYz5kkgpfDAByfDVgAuvtSFLHSqoMWmmSZBU1LZtN2sDsAS6RVQSevfxv39kyty",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "BLS12381_G1",
|
|
||||||
"x": "im0OQGMTkh4YEhAl16hQwUQTcOaRqIqThqtSwksFK7WaH6Qywypmc3VIDyydmYTe"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "BLS12381_G1",
|
|
||||||
"x": "im0OQGMTkh4YEhAl16hQwUQTcOaRqIqThqtSwksFK7WaH6Qywypmc3VIDyydmYTe",
|
|
||||||
"d": "S7Z1TuL05WHge8od0_mW8b3sRM747caCffsLwS6JZ-c"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk#z3tEEysHYz5kkgpfDAByfDVgAuvtSFLHSqoMWmmSZBU1LZtN2sDsAS6RVQSevfxv39kyty",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "BLS12381_G1",
|
|
||||||
"x": "im0OQGMTkh4YEhAl16hQwUQTcOaRqIqThqtSwksFK7WaH6Qywypmc3VIDyydmYTe"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk#z3tEEysHYz5kkgpfDAByfDVgAuvtSFLHSqoMWmmSZBU1LZtN2sDsAS6RVQSevfxv39kyty"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk#z3tEEysHYz5kkgpfDAByfDVgAuvtSFLHSqoMWmmSZBU1LZtN2sDsAS6RVQSevfxv39kyty"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk#z3tEEysHYz5kkgpfDAByfDVgAuvtSFLHSqoMWmmSZBU1LZtN2sDsAS6RVQSevfxv39kyty"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z5TcCmGLu7HrkT5FTnejDTKcH11LPMQLXMPHTRyzY4KdRvqpPLprH7s1ddWFD38cAkZoiDtofUmJVZyEweUTfwjG5H3znk3ir4tzmuDBUSNbNQ7U6jJqj5bkQLKRaQB1bpFJKGLEq3EBwsfPutL5D7p78kFeLNHznqbf5oGpik7ScaDbGLaTLh1Jtadi6VmPNNd44Cojk#z3tEEysHYz5kkgpfDAByfDVgAuvtSFLHSqoMWmmSZBU1LZtN2sDsAS6RVQSevfxv39kyty"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,293 +0,0 @@
|
|||||||
{
|
|
||||||
"did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp": {
|
|
||||||
"seed": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"controller": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp",
|
|
||||||
"publicKeyBase58": "4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS"
|
|
||||||
},
|
|
||||||
"keyAgreementKeyPair": {
|
|
||||||
"id": "#z6LShs9GGnqk85isEBzzshkuVWrVKsRp24GnDuHk8QWkARMW",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp",
|
|
||||||
"publicKeyBase58": "7By6kV2t2d188odEM4ExAve1UithKT6dLva4dwsDT3ak",
|
|
||||||
"privateKeyBase58": "6QN8DfuN9hjgHgPvLXqgzqYE3jRRGRrmJQZkd5tL8paR"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/ed25519-2018/v1",
|
|
||||||
"https://w3id.org/security/suites/x25519-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"controller": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp",
|
|
||||||
"publicKeyBase58": "4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6LShs9GGnqk85isEBzzshkuVWrVKsRp24GnDuHk8QWkARMW",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp",
|
|
||||||
"publicKeyBase58": "7By6kV2t2d188odEM4ExAve1UithKT6dLva4dwsDT3ak"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp#z6LShs9GGnqk85isEBzzshkuVWrVKsRp24GnDuHk8QWkARMW"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG": {
|
|
||||||
"seed": "0000000000000000000000000000000000000000000000000000000000000001",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"controller": "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
|
|
||||||
"publicKeyBase58": "6ASf5EcmmEHTgDJ4X4ZT5vT6iHVJBXPg5AN5YoTCpGWt"
|
|
||||||
},
|
|
||||||
"keyAgreementKeyPair": {
|
|
||||||
"id": "#z6LSrHyXiPBhUbvPUtyUCdf32sniiMGPTAesgHrtEa4FePtr",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
|
|
||||||
"publicKeyBase58": "FcoNC5NqP9CePWbhfz95iHaEsCjGkZUioK9Ck7Qiw286",
|
|
||||||
"privateKeyBase58": "HBTcN2MrXNRj9xF9oi8QqYyuEPv3JLLjQKuEgW9oxVKP"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/ed25519-2018/v1",
|
|
||||||
"https://w3id.org/security/suites/x25519-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG#z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"controller": "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
|
|
||||||
"publicKeyBase58": "6ASf5EcmmEHTgDJ4X4ZT5vT6iHVJBXPg5AN5YoTCpGWt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG#z6LSrHyXiPBhUbvPUtyUCdf32sniiMGPTAesgHrtEa4FePtr",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
|
|
||||||
"publicKeyBase58": "FcoNC5NqP9CePWbhfz95iHaEsCjGkZUioK9Ck7Qiw286"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG#z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG#z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG#z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG#z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG#z6LSrHyXiPBhUbvPUtyUCdf32sniiMGPTAesgHrtEa4FePtr"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf": {
|
|
||||||
"seed": "0000000000000000000000000000000000000000000000000000000000000002",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"controller": "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
|
|
||||||
"publicKeyBase58": "8pM1DN3RiT8vbom5u1sNryaNT1nyL8CTTW3b5PwWXRBH"
|
|
||||||
},
|
|
||||||
"keyAgreementKeyPair": {
|
|
||||||
"id": "#z6LSkkqoZRC34AEpbkhZCqLDcHQVAxuLpQ7kC8XCXMVUfvjE",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
|
|
||||||
"publicKeyBase58": "A5fe37PAxhX5WNKngBpGHhC1KpNE7nwbK9oX2tqwxYxU",
|
|
||||||
"privateKeyBase58": "ACa4PPJ1LnPNq1iwS33V3Akh7WtnC71WkKFZ9ccM6sX2"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/ed25519-2018/v1",
|
|
||||||
"https://w3id.org/security/suites/x25519-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf#z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"controller": "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
|
|
||||||
"publicKeyBase58": "8pM1DN3RiT8vbom5u1sNryaNT1nyL8CTTW3b5PwWXRBH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf#z6LSkkqoZRC34AEpbkhZCqLDcHQVAxuLpQ7kC8XCXMVUfvjE",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
|
|
||||||
"publicKeyBase58": "A5fe37PAxhX5WNKngBpGHhC1KpNE7nwbK9oX2tqwxYxU"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf#z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf#z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf#z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf#z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf#z6LSkkqoZRC34AEpbkhZCqLDcHQVAxuLpQ7kC8XCXMVUfvjE"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ": {
|
|
||||||
"seed": "0000000000000000000000000000000000000000000000000000000000000003",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"controller": "did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ",
|
|
||||||
"publicKeyBase58": "HPYVwAQmskwT1qEEeRzhoomyfyupJGASQQtCXSNG8XS2"
|
|
||||||
},
|
|
||||||
"keyAgreementKeyPair": {
|
|
||||||
"id": "#z6LSiUo6AEDat8Ze4nQzDo67SGuHLLwsUGkxndHGUjsywHow",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ",
|
|
||||||
"publicKeyBase58": "7ocvdvQinfqtyQ3Dh9aA7ggoVCQkmfaoueZazHETDv3B",
|
|
||||||
"privateKeyBase58": "FZrzd1osCnbK6y6MJzMBW1RcVfL524sNKhSbqRwMuwHT"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/ed25519-2018/v1",
|
|
||||||
"https://w3id.org/security/suites/x25519-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ#z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"controller": "did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ",
|
|
||||||
"publicKeyBase58": "HPYVwAQmskwT1qEEeRzhoomyfyupJGASQQtCXSNG8XS2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ#z6LSiUo6AEDat8Ze4nQzDo67SGuHLLwsUGkxndHGUjsywHow",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ",
|
|
||||||
"publicKeyBase58": "7ocvdvQinfqtyQ3Dh9aA7ggoVCQkmfaoueZazHETDv3B"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ#z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ#z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ#z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ#z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6MkvqoYXQfDDJRv8L4wKzxYeuKyVZBfi9Qo6Ro8MiLH3kDQ#z6LSiUo6AEDat8Ze4nQzDo67SGuHLLwsUGkxndHGUjsywHow"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU": {
|
|
||||||
"seed": "0000000000000000000000000000000000000000000000000000000000000005",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "OKP",
|
|
||||||
"crv": "Ed25519",
|
|
||||||
"x": "_eT7oDCtAC98L31MMx9J0T-w7HR-zuvsY08f9MvKne8"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "OKP",
|
|
||||||
"crv": "Ed25519",
|
|
||||||
"x": "_eT7oDCtAC98L31MMx9J0T-w7HR-zuvsY08f9MvKne8",
|
|
||||||
"d": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"keyAgreementKeyPair": {
|
|
||||||
"id": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6LSmArkPSdTKjEESsExHRrSwUzYUHgDuWDewXc4nocasvFU",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "OKP",
|
|
||||||
"crv": "X25519",
|
|
||||||
"x": "jRIz3oriXDNZmnb35XQb7K1UIlz3ae1ao1YSqLeBXHs"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "OKP",
|
|
||||||
"crv": "X25519",
|
|
||||||
"x": "jRIz3oriXDNZmnb35XQb7K1UIlz3ae1ao1YSqLeBXHs",
|
|
||||||
"d": "aEAAB3VBFPCQtgF3N__wRiXhMOgeiRGstpPC3gnJ1Eo"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "OKP",
|
|
||||||
"crv": "Ed25519",
|
|
||||||
"x": "_eT7oDCtAC98L31MMx9J0T-w7HR-zuvsY08f9MvKne8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6LSmArkPSdTKjEESsExHRrSwUzYUHgDuWDewXc4nocasvFU",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "OKP",
|
|
||||||
"crv": "X25519",
|
|
||||||
"x": "jRIz3oriXDNZmnb35XQb7K1UIlz3ae1ao1YSqLeBXHs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6MkwYMhwTvsq376YBAcJHy3vyRWzBgn5vKfVqqDCgm7XVKU#z6LSmArkPSdTKjEESsExHRrSwUzYUHgDuWDewXc4nocasvFU"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,371 +0,0 @@
|
|||||||
{
|
|
||||||
"did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv": {
|
|
||||||
"verificationMethod": {
|
|
||||||
"id": "#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-256",
|
|
||||||
"x": "igrFmi0whuihKnj9R3Om1SoMph72wUGeFaBbzG2vzns",
|
|
||||||
"y": "efsX5b10x8yjyrj4ny3pGfLcY7Xby1KzgqOdqnsrJIM"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-256",
|
|
||||||
"x": "igrFmi0whuihKnj9R3Om1SoMph72wUGeFaBbzG2vzns",
|
|
||||||
"y": "efsX5b10x8yjyrj4ny3pGfLcY7Xby1KzgqOdqnsrJIM",
|
|
||||||
"d": "gPh-VvVS8MbvKQ9LSVVmfnxnKjHn4Tqj0bmbpehRlpc"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-256",
|
|
||||||
"x": "igrFmi0whuihKnj9R3Om1SoMph72wUGeFaBbzG2vzns",
|
|
||||||
"y": "efsX5b10x8yjyrj4ny3pGfLcY7Xby1KzgqOdqnsrJIM"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv#zDnaerx9CtbPJ1q36T5Ln5wYt3MQYeGRG5ehnPAmxcf5mDZpv"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169": {
|
|
||||||
"verificationMethod": {
|
|
||||||
"id": "#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-256",
|
|
||||||
"x": "fyNYMN0976ci7xqiSdag3buk-ZCwgXU4kz9XNkBlNUI",
|
|
||||||
"y": "hW2ojTNfH7Jbi8--CJUo3OCbH3y5n91g-IMA9MLMbTU"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-256",
|
|
||||||
"x": "fyNYMN0976ci7xqiSdag3buk-ZCwgXU4kz9XNkBlNUI",
|
|
||||||
"y": "hW2ojTNfH7Jbi8--CJUo3OCbH3y5n91g-IMA9MLMbTU",
|
|
||||||
"d": "YjRs6vNvw4sYrzVVY8ipkEpDAD9PFqw1sUnvPRMA-WI"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-256",
|
|
||||||
"x": "fyNYMN0976ci7xqiSdag3buk-ZCwgXU4kz9XNkBlNUI",
|
|
||||||
"y": "hW2ojTNfH7Jbi8--CJUo3OCbH3y5n91g-IMA9MLMbTU"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169#zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9": {
|
|
||||||
"verificationMethod": {
|
|
||||||
"id": "#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-384",
|
|
||||||
"x": "lInTxl8fjLKp_UCrxI0WDklahi-7-_6JbtiHjiRvMvhedhKVdHBfi2HCY8t_QJyc",
|
|
||||||
"y": "y6N1IC-2mXxHreETBW7K3mBcw0qGr3CWHCs-yl09yCQRLcyfGv7XhqAngHOu51Zv"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-384",
|
|
||||||
"x": "lInTxl8fjLKp_UCrxI0WDklahi-7-_6JbtiHjiRvMvhedhKVdHBfi2HCY8t_QJyc",
|
|
||||||
"y": "y6N1IC-2mXxHreETBW7K3mBcw0qGr3CWHCs-yl09yCQRLcyfGv7XhqAngHOu51Zv",
|
|
||||||
"d": "hAyGZNj9031guBCdpAOaZkO-E5m-LKLYnMIq0-msrp8JLctseaOeNTHmP3uKVWwX"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-384",
|
|
||||||
"x": "lInTxl8fjLKp_UCrxI0WDklahi-7-_6JbtiHjiRvMvhedhKVdHBfi2HCY8t_QJyc",
|
|
||||||
"y": "y6N1IC-2mXxHreETBW7K3mBcw0qGr3CWHCs-yl09yCQRLcyfGv7XhqAngHOu51Zv"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9#z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54": {
|
|
||||||
"verificationMethod": {
|
|
||||||
"id": "#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-384",
|
|
||||||
"x": "CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT",
|
|
||||||
"y": "Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-384",
|
|
||||||
"x": "CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT",
|
|
||||||
"y": "Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_",
|
|
||||||
"d": "Xe1HHeh-UsrJPRNLR_Y06VTrWpZYBXi7a7kiRqCgwnAOlJZPwE-xzL3DIIVMavAL"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-384",
|
|
||||||
"x": "CA-iNoHDg1lL8pvX3d1uvExzVfCz7Rn6tW781Ub8K5MrDf2IMPyL0RTDiaLHC1JT",
|
|
||||||
"y": "Kpnrn8DkXUD3ge4mFxi-DKr0DYO2KuJdwNBrhzLRtfMa3WFMZBiPKUPfJj8dYNl_"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54#z82LkvCwHNreneWpsgPEbV3gu1C6NFJEBg4srfJ5gdxEsMGRJUz2sG9FE42shbn2xkZJh54"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7": {
|
|
||||||
"verificationMethod": {
|
|
||||||
"id": "#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-521",
|
|
||||||
"x": "ASUHPMyichQ0QbHZ9ofNx_l4y7luncn5feKLo3OpJ2nSbZoC7mffolj5uy7s6KSKXFmnNWxGJ42IOrjZ47qqwqyS",
|
|
||||||
"y": "AW9ziIC4ZQQVSNmLlp59yYKrjRY0_VqO-GOIYQ9tYpPraBKUloEId6cI_vynCzlZWZtWpgOM3HPhYEgawQ703RjC"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-521",
|
|
||||||
"x": "ASUHPMyichQ0QbHZ9ofNx_l4y7luncn5feKLo3OpJ2nSbZoC7mffolj5uy7s6KSKXFmnNWxGJ42IOrjZ47qqwqyS",
|
|
||||||
"y": "AW9ziIC4ZQQVSNmLlp59yYKrjRY0_VqO-GOIYQ9tYpPraBKUloEId6cI_vynCzlZWZtWpgOM3HPhYEgawQ703RjC",
|
|
||||||
"d": "AHwRaNaGs0jkj_pT6PK2aHep7dJK-yxyoL2bIfVRAceq1baxoiFDo3W14c8E2YZn1k5S53r4a11flhQdaB5guJ_X"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-521",
|
|
||||||
"x": "ASUHPMyichQ0QbHZ9ofNx_l4y7luncn5feKLo3OpJ2nSbZoC7mffolj5uy7s6KSKXFmnNWxGJ42IOrjZ47qqwqyS",
|
|
||||||
"y": "AW9ziIC4ZQQVSNmLlp59yYKrjRY0_VqO-GOIYQ9tYpPraBKUloEId6cI_vynCzlZWZtWpgOM3HPhYEgawQ703RjC"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7#z2J9gaYxrKVpdoG9A4gRnmpnRCcxU6agDtFVVBVdn1JedouoZN7SzcyREXXzWgt3gGiwpoHq7K68X4m32D8HgzG8wv3sY5j7"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f": {
|
|
||||||
"verificationMethod": {
|
|
||||||
"id": "#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-521",
|
|
||||||
"x": "AQgyFy6EwH3_u_KXPw8aTXTY7WSVytmbuJeFpq4U6LipxtSmBJe_jjRzms9qubnwm_fGoHMQlvQ1vzS2YLusR2V0",
|
|
||||||
"y": "Ab06MCcgoG7dM2I-VppdLV1k3lDoeHMvyYqHVfP05Ep2O7Zu0Qwd6IVzfZi9K0KMDud22wdnGUpUtFukZo0EeO15"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-521",
|
|
||||||
"x": "AQgyFy6EwH3_u_KXPw8aTXTY7WSVytmbuJeFpq4U6LipxtSmBJe_jjRzms9qubnwm_fGoHMQlvQ1vzS2YLusR2V0",
|
|
||||||
"y": "Ab06MCcgoG7dM2I-VppdLV1k3lDoeHMvyYqHVfP05Ep2O7Zu0Qwd6IVzfZi9K0KMDud22wdnGUpUtFukZo0EeO15",
|
|
||||||
"d": "AbheZ-AA58LP4BpopCGCLH8ZoMdkdJaVOS6KK2NNmDCisr5_Ifxl-qcunrkOJ0CSauA4LJyNbCWcy28Bo6zgHTXQ"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "P-521",
|
|
||||||
"x": "AQgyFy6EwH3_u_KXPw8aTXTY7WSVytmbuJeFpq4U6LipxtSmBJe_jjRzms9qubnwm_fGoHMQlvQ1vzS2YLusR2V0",
|
|
||||||
"y": "Ab06MCcgoG7dM2I-VppdLV1k3lDoeHMvyYqHVfP05Ep2O7Zu0Qwd6IVzfZi9K0KMDud22wdnGUpUtFukZo0EeO15"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f#z2J9gcGdb2nEyMDmzQYv2QZQcM1vXktvy1Pw4MduSWxGabLZ9XESSWLQgbuPhwnXN7zP7HpTzWqrMTzaY5zWe6hpzJ2jnw4f"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb": {
|
|
||||||
"verificationMethod": {
|
|
||||||
"id": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb#zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb",
|
|
||||||
"type": "P256Key2021",
|
|
||||||
"controller": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb",
|
|
||||||
"publicKeyBase58": "ekVhkcBFq3w7jULLkBVye6PwaTuMbhJYuzwFnNcgQAPV",
|
|
||||||
"privateKeyBase58": "9p4VRzdmhsnq869vQjVCTrRry7u4TtfRxhvBFJTGU2Cp"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/multikey-2021/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb#zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb",
|
|
||||||
"type": "P256Key2021",
|
|
||||||
"controller": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb",
|
|
||||||
"publicKeyBase58": "ekVhkcBFq3w7jULLkBVye6PwaTuMbhJYuzwFnNcgQAPV"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb#zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb#zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb#zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb#zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb#zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
{
|
|
||||||
"did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i": {
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "RSA",
|
|
||||||
"n": "sbX82NTV6IylxCh7MfV4hlyvaniCajuP97GyOqSvTmoEdBOflFvZ06kR_9D6ctt45Fk6hskfnag2GG69NALVH2o4RCR6tQiLRpKcMRtDYE_thEmfBvDzm_VVkOIYfxu-Ipuo9J_S5XDNDjczx2v-3oDh5-CIHkU46hvFeCvpUS-L8TJSbgX0kjVk_m4eIb9wh63rtmD6Uz_KBtCo5mmR4TEtcLZKYdqMp3wCjN-TlgHiz_4oVXWbHUefCEe8rFnX1iQnpDHU49_SaXQoud1jCaexFn25n-Aa8f8bc5Vm-5SeRwidHa6ErvEhTvf1dz6GoNPp2iRvm-wJ1gxwWJEYPQ",
|
|
||||||
"e": "AQAB"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "RSA",
|
|
||||||
"n": "sbX82NTV6IylxCh7MfV4hlyvaniCajuP97GyOqSvTmoEdBOflFvZ06kR_9D6ctt45Fk6hskfnag2GG69NALVH2o4RCR6tQiLRpKcMRtDYE_thEmfBvDzm_VVkOIYfxu-Ipuo9J_S5XDNDjczx2v-3oDh5-CIHkU46hvFeCvpUS-L8TJSbgX0kjVk_m4eIb9wh63rtmD6Uz_KBtCo5mmR4TEtcLZKYdqMp3wCjN-TlgHiz_4oVXWbHUefCEe8rFnX1iQnpDHU49_SaXQoud1jCaexFn25n-Aa8f8bc5Vm-5SeRwidHa6ErvEhTvf1dz6GoNPp2iRvm-wJ1gxwWJEYPQ",
|
|
||||||
"e": "AQAB",
|
|
||||||
"d": "Eym3sT4KLwBzo5pl5nY83-hAti92iLQRizkrKe22RbNi9Y1kKOBatdtGaJqFVztZZu5ERGKNuTd5VdsjJeekSbXviVGRtdHNCvgmRZlWA5261AgIUPxMmKW062GmGJbKQvscFfziBgHK6tyDBd8cZavqMFHi-7ilMYF7IsFBcJKM85x_30pnfd4YwhGQIc9hzv238aOwYKg8c-MzYhEVUnL273jaiLVlfZWQ5ca-GXJHmdOb_Y4fE5gpXfPFBseqleXsMp0VuXxCEsN30LIJHYscdPtbzLD3LFbuMJglFbQqYqssqymILGqJ7Tc2mB2LmXevfqRWz5D7A_K1WzvuoQ",
|
|
||||||
"p": "ANwlk-eVXPQplCmr7VddX8MAlN5YWvfXkbJe2KOhyS7naSlfMyeW6I0z6q6MAI4h8cs9yEzwmN1oEl_6tZ_-NPd1Oda2Hq5jHx0Jq2P5exIMMbzTTHbB-LjMB4c-b1DZLOrL7ZpCS-CcEHvBz4phzHa7gqz2SrNIGozufbjS_tK5",
|
|
||||||
"q": "AM6nKRFqRgHiUtGc0xJawpXJeokGhJQFfinDlakjkptuRQNv0BOz8fRUxk6zwwYrx-T_Yk-0oAFsD8qWIgiXg8Wf0bdRW0L0dIH4c6ff3mSREXeAT2h3XDaF0F1YKns08WyYWtOuIiYWChyO9sweK7AUuaOJ-6lr6lElzTGHVf-l",
|
|
||||||
"dp": "AIHFBPK2cRzchaIq3rVpLVHdveNzYexG_nOOxVVvwRANCUiB_b2Qj3Ts7aIGlS0zhTyxJql0Cig5eNtrBjVRvBdC2t1ebaeOdoC_enBsV8fDuG3-gExg-ySz4JwwiZ2252tg2qbb_a5hULYjARwpmkVDMzyR0mbsUfpRe3q_pcbB",
|
|
||||||
"dq": "Id2bCVOVLXHdiKReor9k7A8cmaAL0gYkasu2lwVRXU9w1-NXAiOXHydVaEhlSXmbRJflkJJVNmZzIAwCf830tko-oAAhKJPPFA2XRoeVdn2fkynf2YrV_cloICP2skI23kkJeW8sAXnTJmL3ZvP6zNxYn8hZCaa5u5qqSdeX7FE",
|
|
||||||
"qi": "WKIToXXnjl7GDbz7jCNbX9nWYOE5BDNzVmwiVOnyGoTZfwJ_qtgizj7pOapxi6dT9S9mMavmeAi6LAsEe1WUWtaKSNhbNh0PUGGXlXHGlhkS8jI1ot0e-scrHAuACE567YQ4VurpNorPKtZ5UENXIn74DEmt4l5m6902VF3X5Wo"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i#z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "RSA",
|
|
||||||
"n": "sbX82NTV6IylxCh7MfV4hlyvaniCajuP97GyOqSvTmoEdBOflFvZ06kR_9D6ctt45Fk6hskfnag2GG69NALVH2o4RCR6tQiLRpKcMRtDYE_thEmfBvDzm_VVkOIYfxu-Ipuo9J_S5XDNDjczx2v-3oDh5-CIHkU46hvFeCvpUS-L8TJSbgX0kjVk_m4eIb9wh63rtmD6Uz_KBtCo5mmR4TEtcLZKYdqMp3wCjN-TlgHiz_4oVXWbHUefCEe8rFnX1iQnpDHU49_SaXQoud1jCaexFn25n-Aa8f8bc5Vm-5SeRwidHa6ErvEhTvf1dz6GoNPp2iRvm-wJ1gxwWJEYPQ",
|
|
||||||
"e": "AQAB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i#z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i"
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i#z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i#z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i#z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i#z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2": {
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "RSA",
|
|
||||||
"n": "qMCkFFRFWtzUyZeK8mgJdyM6SEQcXC5E6JwCRVDld-jlJs8sXNOE_vliexq34wZRQ4hk53-JPFlvZ_QjRgIxdUxSMiZ3S5hlNVvvRaue6SMakA9ugQhnfXaWORro0UbPuHLms-bg5StDP8-8tIezu9c1H1FjwPcdbV6rAvKhyhnsM10qP3v2CPbdE0q3FOsihoKuTelImtO110E7N6fLn4U3EYbC4OyViqlrP1o_1M-R-tiM1cb4pD7XKJnIs6ryZdfOQSPBJwjNqSdN6Py_tdrFgPDTyacSSdpTVADOM2IMAoYbhV1N5APhnjOHBRFyKkF1HffQKpmXQLBqvUNNjuhmpVKWBtrTdcCKrglFXiw0cKGHKxIirjmiOlB_HYHg5UdosyE3_1Txct2U7-WBB6QXak1UgxCzgKYBDI8UPA0RlkUuHHP_Zg0fVXrXIInHO04MYxUeSps5qqyP6dJBu_v_BDn3zUq6LYFwJ_-xsU7zbrKYB4jaRlHPoCj_eDC-rSA2uQ4KXHBB8_aAqNFC9ukWxc26Ifz9dF968DLuL30bi-ZAa2oUh492Pw1bg89J7i4qTsOOfpQvGyDV7TGhKuUG3Hbumfr2w16S-_3EI2RIyd1nYsflE6ZmCkZQMG_lwDAFXaqfyGKEDouJuja4XH8r4fGWeGTrozIoniXT1HU",
|
|
||||||
"e": "AQAB"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "RSA",
|
|
||||||
"n": "qMCkFFRFWtzUyZeK8mgJdyM6SEQcXC5E6JwCRVDld-jlJs8sXNOE_vliexq34wZRQ4hk53-JPFlvZ_QjRgIxdUxSMiZ3S5hlNVvvRaue6SMakA9ugQhnfXaWORro0UbPuHLms-bg5StDP8-8tIezu9c1H1FjwPcdbV6rAvKhyhnsM10qP3v2CPbdE0q3FOsihoKuTelImtO110E7N6fLn4U3EYbC4OyViqlrP1o_1M-R-tiM1cb4pD7XKJnIs6ryZdfOQSPBJwjNqSdN6Py_tdrFgPDTyacSSdpTVADOM2IMAoYbhV1N5APhnjOHBRFyKkF1HffQKpmXQLBqvUNNjuhmpVKWBtrTdcCKrglFXiw0cKGHKxIirjmiOlB_HYHg5UdosyE3_1Txct2U7-WBB6QXak1UgxCzgKYBDI8UPA0RlkUuHHP_Zg0fVXrXIInHO04MYxUeSps5qqyP6dJBu_v_BDn3zUq6LYFwJ_-xsU7zbrKYB4jaRlHPoCj_eDC-rSA2uQ4KXHBB8_aAqNFC9ukWxc26Ifz9dF968DLuL30bi-ZAa2oUh492Pw1bg89J7i4qTsOOfpQvGyDV7TGhKuUG3Hbumfr2w16S-_3EI2RIyd1nYsflE6ZmCkZQMG_lwDAFXaqfyGKEDouJuja4XH8r4fGWeGTrozIoniXT1HU",
|
|
||||||
"e": "AQAB",
|
|
||||||
"d": "TMq1H-clVG7PihkjCqJbRFLMj9wmx6_qfauYwPBKK-HYfWujdW5vxBO6Q-jpqy7RxhiISmxYCBVuw_BuKMqQtR8Q_G9StBzaWYjHfn3Vp6Poz4umLqOjbI2NWNks_ybpGbd30oAK8V5ZkO04ozJpkN4i92hzK3mIc5-z1HiTNUPMn6cStab0VCn6em_ylltV774CEcRJ3OLgid7OUspRt_rID3qyreYbOulTu5WXHIGEnZDzrciIlz1dbcVldpUhD0VAP5ZErD2uUP5oztBNcTTn0YBF8CrOALuQVdaz_t_sNS3P0kWeT1eQ0QwDskO5Hw-Aey2tFeWk1bQyLoQ1A0jsw8mDbkO2zrGfJoxmVBkueTK-q64_n1kV7W1aeJFRj4NwEWmwcrs8GSOGOn38fGB_Y3Kci04qvD6L0QZbFkAVzcJracnxbTdHCEX0jsAAPbYC8M_8PyrPJvPC4IAAWTRrSRbysb7r7viRf4A1vTK9VT7uYyxj7Kzx2cU12d9QBXYfdQ2744bUE7HqN-Vh2rHvv2l5v6vzBRoZ5_OhHHVeUYwC9LouE9lSVAObbFM-Qe1SvzbbwN91LziI7UzUc_xMAEiNwt6PpnIAWAhdvSRawEllTwUcn89udHd5UhiAcm-RQOqXIdA9Aly6d8TT8R1p-ZnQ_gbZyBZeS39AuvU=",
|
|
||||||
"p": "1p4cypsJeTyVXXc5bQpvzVenPy78OHXtGcFQnbTjW8x1GsvJ-rlHAcjUImd44pgNQNe-iYpeUg3KqfONeedNgQCFd8kP7GoVAd45mEvsGBXvjoCXOBMQlsf8UU_hm_LKhVvTvTmMGoudnNv5qYNDMCGJGzwoG-aSvROlIoXzHmDnusZ-hKsDxM9j0PPz21t99Y_Fr30Oq3FIWXPVmLYmfyZYQkxm9a9WNMkqRbwJuMwGI6V9ABsQ1dW_KJzp_aEBbJLcDr9DsWhm9ErLeAlzyaDYEai6wCtKm9em4LDwCbKhJq3hWEp1sIG-hwx1sk7N4i-b8lBijjEQE-dbSQxUlw==",
|
|
||||||
"q": "yUqMejfrttGujadj7Uf7q91KM7nbQGny4TjD-CqibcFE-s2_DExCgP1wfhUPfJr2uPQDIe4g12uaNoa5GbCSDaQwEmQpurC_5mazt-z-_tbI24hoPQm5Hq67fZz-jDE_3OccLPLIWtajJqmxHbbB5VqskMuXo8KDxPRfBQBhykmb9_5M8pY2ggZOV4shCUn5E9nOnvibvw5Wx4CBtWUtca4rhpd3mVen1d8xCe4xTG_ni_w1lwdxzU1GmRFqgTuZWzL0r2FKzJg7hju1SOEe4tKMxQ-xs2HyNaMM__SLsNmS3lsYZ8r2hqcjEMQQZI0T_O-3BjIpyg986P8j055E0w==",
|
|
||||||
"dp": "DujzJRw6P0L3OYQT6EBmXgSt6NTRzvZaX4SvnhU4CmOc6xynTpTamwQhwLYhjtRzb0LNyO5k-RxeLQpvlL1-A-1OWHEOeyUvim6u36a-ozm659KFLu8cIu2H2PpMuTHX4gXsIuRBmIKEk6YwpRcqbsiVpt-6BZ4yKZKY0Vou9rhSwQYTOhJLc7vYumaIVX_4szumxzdP8pcvKI_EkhRtfj3iudBnAsCIo6gqGKgkoMMD1iwkEALRW5m66w5jrywlVi6pvRiKkmOna2da1V8KvUJAYJGxT7JyP3tu64M_Wd0gFvjTg_fAT1_kJau27YlOAl2-Xso43poH_OoAzIVfxw==",
|
|
||||||
"dq": "XI6Z76z9BxB9mgcpTLc3wzw63XQNnB3bn7JRcjBwhdVD2at3uLjsL5HaAy-98kbzQfJ56kUr9sI0o_Po8yYc0ob3z80c3wpdAx2gb-dbDWVH8KJVhBOPestPzR--cEpJGlNuwkBU3mgplyKaHZamq8a46M-lB5jurEbN1mfpj3GvdSYKzdVCdSFfLqP76eCI1pblinW4b-6w-oVdn0JJ1icHPpkxVmJW-2Hok69iHcqrBtRO9AZpTsTEvKekeI4mIyhYGLi9AzzQyhV0c3GImTXFoutng5t7GyzBUoRpI0W4YeQzYa6TEzGRTylIfGPemATF_OReENp0TlLbb3gsHw==",
|
|
||||||
"qi": "m7uZk4AsOfJ1V2RY8lmEF518toCV7juKuS_b_OUx8B0dRG0_kbF1cH-Tmrgsya3bwkYx5HeZG81rX7SRjh-0nVPOMW3tGqU5U9f59DXqvOItJIJ6wvWvWXnuna2-NstYCotFQWadIKjk4wjEKj-a4NJt4D_F4csyeyqWOH2DiUFzBGGxxdEoD5t_HEeNXuWQ6-SiV0x5ZVMln3TSh7IOMl70Smm8HcQF5mOsWg3N0wIg-yffxPrs6r15TRuW1MfT-bZk2GLrtHF1TkIoT1e00jWK4eBl2oRxiJGONUBMTEHV85Fr0yztnA99AgHnrMbE_4ehvev4h5DEWvFyFuJN_g=="
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2#zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "RSA",
|
|
||||||
"n": "qMCkFFRFWtzUyZeK8mgJdyM6SEQcXC5E6JwCRVDld-jlJs8sXNOE_vliexq34wZRQ4hk53-JPFlvZ_QjRgIxdUxSMiZ3S5hlNVvvRaue6SMakA9ugQhnfXaWORro0UbPuHLms-bg5StDP8-8tIezu9c1H1FjwPcdbV6rAvKhyhnsM10qP3v2CPbdE0q3FOsihoKuTelImtO110E7N6fLn4U3EYbC4OyViqlrP1o_1M-R-tiM1cb4pD7XKJnIs6ryZdfOQSPBJwjNqSdN6Py_tdrFgPDTyacSSdpTVADOM2IMAoYbhV1N5APhnjOHBRFyKkF1HffQKpmXQLBqvUNNjuhmpVKWBtrTdcCKrglFXiw0cKGHKxIirjmiOlB_HYHg5UdosyE3_1Txct2U7-WBB6QXak1UgxCzgKYBDI8UPA0RlkUuHHP_Zg0fVXrXIInHO04MYxUeSps5qqyP6dJBu_v_BDn3zUq6LYFwJ_-xsU7zbrKYB4jaRlHPoCj_eDC-rSA2uQ4KXHBB8_aAqNFC9ukWxc26Ifz9dF968DLuL30bi-ZAa2oUh492Pw1bg89J7i4qTsOOfpQvGyDV7TGhKuUG3Hbumfr2w16S-_3EI2RIyd1nYsflE6ZmCkZQMG_lwDAFXaqfyGKEDouJuja4XH8r4fGWeGTrozIoniXT1HU",
|
|
||||||
"e": "AQAB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2#zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2"
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2#zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2#zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2#zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2#zgghBUVkqmWS8e1ioRVp2WN9Vw6x4NvnE9PGAyQsPqM3fnfPf8EdauiRVfBTcVDyzhqM5FFC7ekAvuV1cJHawtfgB9wDcru1hPDobk3hqyedijhgWmsYfJCmodkiiFnjNWATE7PvqTyoCjcmrc8yMRXmFPnoASyT5beUd4YZxTE9VfgmavcPy3BSouNmASMQ8xUXeiRwjb7xBaVTiDRjkmyPD7NYZdXuS93gFhyDFr5b3XLg7Rfj9nHEqtHDa7NmAX7iwDAbMUFEfiDEf9hrqZmpAYJracAjTTR8Cvn6mnDXMLwayNG8dcsXFodxok2qksYF4D8ffUxMRmyyQVQhhhmdSi4YaMPqTnC1J6HTG9Yfb98yGSVaWi4TApUhLXFow2ZvB6vqckCNhjCRL2R4MDUSk71qzxWHgezKyDeyThJgdxydrn1osqH94oSeA346eipkJvKqYREXBKwgB5VL6WF4qAK6sVZxJp2dQBfCPVZ4EbsBQaJXaVK7cNcWG8tZBFWZ79gG9Cu6C4u8yjBS8Ux6dCcJPUTLtixQu4z2n5dCsVSNdnP1EEs8ZerZo5pBgc68w4Yuf9KL3xVxPnAB1nRCBfs9cMU6oL1EdyHbqrTfnjE8HpY164akBqe92LFVsk8RusaGsVPrMekT8emTq5y8v8CabuZg5rDs3f9NPEtogjyx49wiub1FecM5B7QqEcZSYiKHgF4mfkteT2"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
{
|
|
||||||
"did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme": {
|
|
||||||
"seed": "9085d2bef69286a6cbb51623c8fa258629945cd55ca705cc4e66700396894e0c",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme",
|
|
||||||
"publicKeyBase58": "23o6Sau8NxxzXcgSc3PLcNxrzrZpbLeBn1izfv3jbKhuv",
|
|
||||||
"privateKeyBase58": "AjA4cyPUbbfW5wr6iZeRbJLhgH3qDt6q6LMkRw36KpxT"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/secp256k1-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme",
|
|
||||||
"publicKeyBase58": "23o6Sau8NxxzXcgSc3PLcNxrzrZpbLeBn1izfv3jbKhuv"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme#zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2": {
|
|
||||||
"seed": "f0f4df55a2b3ff13051ea814a8f24ad00f2e469af73c363ac7e9fb999a9072ed",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2",
|
|
||||||
"publicKeyBase58": "291KzQhqCPC18PqH83XKhxv1HdqrdnxyS7dh15t2uNRzJ",
|
|
||||||
"privateKeyBase58": "HDbR1D5W3CoNbUKYzUbHH2PRF1atshtVupXgXTQhNB9E"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/secp256k1-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2#zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2",
|
|
||||||
"publicKeyBase58": "291KzQhqCPC18PqH83XKhxv1HdqrdnxyS7dh15t2uNRzJ"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2#zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2#zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2#zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2#zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2#zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N": {
|
|
||||||
"seed": "6b0b91287ae3348f8c2f2552d766f30e3604867e34adc37ccbb74a8e6b893e02",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N",
|
|
||||||
"publicKeyBase58": "oesQ92MLiAkt2pjBcJFbW7H4DvzKJv22cotjYbmC2JEe",
|
|
||||||
"privateKeyBase58": "8CrrWVdzDnvaS7vS5dd2HetFSebwEN46XEFrNDdtWZSZ"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/secp256k1-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N#zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N",
|
|
||||||
"publicKeyBase58": "oesQ92MLiAkt2pjBcJFbW7H4DvzKJv22cotjYbmC2JEe"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N#zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N#zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N#zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N#zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N#zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy": {
|
|
||||||
"seed": "c0a6a7c560d37d7ba81ecee9543721ff48fea3e0fb827d42c1868226540fac15",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy",
|
|
||||||
"publicKeyBase58": "pg3p1vprqePgUoqfAQ1TTgxhL6zLYhHyzooR1pqLxo9F",
|
|
||||||
"privateKeyBase58": "Dy2fnt8ba4NmbRBXas9bo1BtYgpYFr6ThpFhJbuA3PRn"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/secp256k1-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy#zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy",
|
|
||||||
"publicKeyBase58": "pg3p1vprqePgUoqfAQ1TTgxhL6zLYhHyzooR1pqLxo9F"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy#zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy#zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy#zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy#zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy#zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj": {
|
|
||||||
"seed": "175a232d440be1e0788f25488a73d9416c04b6f924bea6354bf05dd2f1a75133",
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "#zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj",
|
|
||||||
"publicKeyBase58": "24waDFAUAS16UpZwQQTXVEAmm17rQRjadjuAeBDW8aqL1",
|
|
||||||
"privateKeyBase58": "2aA6WgZnPiVMBX3LvKSTg3KaFKyzfKpvEacixB3yyTgv"
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/secp256k1-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj#zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj",
|
|
||||||
"type": "EcdsaSecp256k1VerificationKey2019",
|
|
||||||
"controller": "did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj",
|
|
||||||
"publicKeyBase58": "24waDFAUAS16UpZwQQTXVEAmm17rQRjadjuAeBDW8aqL1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj#zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj#zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj#zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj#zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj#zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS": {
|
|
||||||
"verificationKeyPair": {
|
|
||||||
"id": "did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS#zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "secp256k1",
|
|
||||||
"x": "TEIJN9vnTq1EXMkqzo7yN_867-foKc2pREv45Fw_QA8",
|
|
||||||
"y": "9yiymlzdxKCiRbYq7p-ArRB-C1ytjHE-eb7RDTi6rVc"
|
|
||||||
},
|
|
||||||
"privateKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "secp256k1",
|
|
||||||
"x": "TEIJN9vnTq1EXMkqzo7yN_867-foKc2pREv45Fw_QA8",
|
|
||||||
"y": "9yiymlzdxKCiRbYq7p-ArRB-C1ytjHE-eb7RDTi6rVc",
|
|
||||||
"d": "J5yKm7OXFsXDEutteGYeT0CAfQJwIlHLSYkQxKtgiyo"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"didDocument": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS#zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "EC",
|
|
||||||
"crv": "secp256k1",
|
|
||||||
"x": "TEIJN9vnTq1EXMkqzo7yN_867-foKc2pREv45Fw_QA8",
|
|
||||||
"y": "9yiymlzdxKCiRbYq7p-ArRB-C1ytjHE-eb7RDTi6rVc"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"assertionMethod": [
|
|
||||||
"did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS#zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS"
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
"did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS#zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS"
|
|
||||||
],
|
|
||||||
"capabilityInvocation": [
|
|
||||||
"did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS#zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS"
|
|
||||||
],
|
|
||||||
"capabilityDelegation": [
|
|
||||||
"did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS#zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS"
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS#zQ3shjmnWpSDEbYKpaFm4kTs9kXyqG6N2QwCYHNPP4yubqgJS"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
//go:build jwx_es256k
|
|
||||||
|
|
||||||
package testvectors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/ed25519"
|
|
||||||
"crypto/elliptic"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
|
||||||
"github.com/lestrrat-go/jwx/v2/jwk"
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
"github.com/mr-tron/base58"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Vectors map[string]Vector
|
|
||||||
|
|
||||||
// This is pretty gross but the structure allows the repeated Verifier,
|
|
||||||
// PublicKeyJwk and PublicKeyBase58 account for the fact that the test
|
|
||||||
// files are very inconsistent.
|
|
||||||
type Vector struct {
|
|
||||||
VerificationKeyPair Verifier
|
|
||||||
VerificationMethod Verifier
|
|
||||||
PublicKeyJwk json.RawMessage
|
|
||||||
DidDocument json.RawMessage // TODO: if we start producing DID documents, we should test this too
|
|
||||||
}
|
|
||||||
|
|
||||||
type Verifier struct {
|
|
||||||
ID string
|
|
||||||
Type string
|
|
||||||
PublicKeyBase58 string
|
|
||||||
PublicKeyJwk json.RawMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Vector) PubKey() (crypto.PubKey, error) {
|
|
||||||
// If the public key is in base58
|
|
||||||
if pubB58 := v.PubKeyBase58(); len(pubB58) > 0 {
|
|
||||||
pubBytes, err := base58.Decode(pubB58)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t, err := v.PubKeyType()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var unmarshaler crypto.PubKeyUnmarshaller
|
|
||||||
|
|
||||||
switch t {
|
|
||||||
case "Ed25519VerificationKey2018":
|
|
||||||
unmarshaler = crypto.UnmarshalEd25519PublicKey
|
|
||||||
case "EcdsaSecp256k1VerificationKey2019":
|
|
||||||
unmarshaler = crypto.UnmarshalSecp256k1PublicKey
|
|
||||||
// This is weak as it assumes the P256 curve - that's all the vectors contain (for now)
|
|
||||||
case "P256Key2021":
|
|
||||||
unmarshaler = compressedEcdsaPublicKeyUnmarshaler
|
|
||||||
default:
|
|
||||||
return nil, errors.New("failed to resolve unmarshaler")
|
|
||||||
}
|
|
||||||
|
|
||||||
return unmarshaler(pubBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the public key is in a JWK
|
|
||||||
if pubJwk := v.PubKeyJwk(); len(pubJwk) > 0 {
|
|
||||||
key, err := jwk.ParseKey(pubJwk)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var a any
|
|
||||||
|
|
||||||
if err := key.Raw(&a); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch a.(type) {
|
|
||||||
case *ecdsa.PublicKey:
|
|
||||||
epub := a.(*ecdsa.PublicKey)
|
|
||||||
|
|
||||||
if epub.Curve == secp256k1.S256() {
|
|
||||||
bytes := append([]byte{0x04}, append(epub.X.Bytes(), epub.Y.Bytes()...)...)
|
|
||||||
|
|
||||||
return crypto.UnmarshalSecp256k1PublicKey(bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
asn1, err := x509.MarshalPKIXPublicKey(epub)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return crypto.UnmarshalECDSAPublicKey(asn1)
|
|
||||||
case ed25519.PublicKey:
|
|
||||||
return crypto.UnmarshalEd25519PublicKey(a.(ed25519.PublicKey))
|
|
||||||
case *rsa.PublicKey:
|
|
||||||
asn1, err := x509.MarshalPKIXPublicKey(a.(*rsa.PublicKey))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return crypto.UnmarshalRsaPublicKey(asn1)
|
|
||||||
default:
|
|
||||||
return nil, errors.New("unsupported key type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we don't find a public key at all
|
|
||||||
return nil, errors.New("vector's public key not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Vector) PubKeyBase58() string {
|
|
||||||
if len(v.VerificationKeyPair.PublicKeyBase58) > 0 {
|
|
||||||
return v.VerificationKeyPair.PublicKeyBase58
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.VerificationMethod.PublicKeyBase58
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Vector) PubKeyJwk() json.RawMessage {
|
|
||||||
if len(v.VerificationKeyPair.PublicKeyJwk) > 0 {
|
|
||||||
return v.VerificationKeyPair.PublicKeyJwk
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v.VerificationMethod.PublicKeyJwk) > 0 {
|
|
||||||
return v.VerificationMethod.PublicKeyJwk
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.PublicKeyJwk
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Vector) PubKeyType() (string, error) {
|
|
||||||
if len(v.VerificationKeyPair.Type) > 0 {
|
|
||||||
return v.VerificationKeyPair.Type, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v.VerificationMethod.Type) > 0 {
|
|
||||||
return v.VerificationMethod.Type, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", errors.New("vector's type not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
func compressedEcdsaPublicKeyUnmarshaler(data []byte) (crypto.PubKey, error) {
|
|
||||||
x, y := elliptic.UnmarshalCompressed(elliptic.P256(), data)
|
|
||||||
|
|
||||||
ecdsaPublicKey := ecdsa.PublicKey{
|
|
||||||
Curve: elliptic.P256(),
|
|
||||||
X: x,
|
|
||||||
Y: y,
|
|
||||||
}
|
|
||||||
|
|
||||||
asn1, err := x509.MarshalPKIXPublicKey(&ecdsaPublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return crypto.UnmarshalECDSAPublicKey(asn1)
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
{
|
|
||||||
"didDocument": {
|
|
||||||
"did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/x25519-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F#z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F",
|
|
||||||
"publicKeyBase58": "4Dy8E9UaZscuPUf2GLxV44RCNL7oxmEXXkgWXaug1WKV"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F#z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"did:key:z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/x25519-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha#z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha",
|
|
||||||
"publicKeyBase58": "J3PiFeuSyLugy4DKn87TwK5cnruRgPtxouzXUqg99Avp"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha#z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"did:key:z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/x25519-2019/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ#z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ",
|
|
||||||
"type": "X25519KeyAgreementKey2019",
|
|
||||||
"controller": "did:key:z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ",
|
|
||||||
"publicKeyBase58": "CgTbngDMe7yHHfxPMvhpaFRpFoQWKgXAgwenJj8PsFDe"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ#z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"did:key:z6LSrzxMVydCourtpA6JLEYupT7ZUQ34hLfQZfRN5H47zLdz": {
|
|
||||||
"@context": [
|
|
||||||
"https://www.w3.org/ns/did/v1",
|
|
||||||
"https://w3id.org/security/suites/jws-2020/v1"
|
|
||||||
],
|
|
||||||
"id": "did:key:z6LSrzxMVydCourtpA6JLEYupT7ZUQ34hLfQZfRN5H47zLdz",
|
|
||||||
"verificationMethod": [
|
|
||||||
{
|
|
||||||
"id": "did:key:z6LSrzxMVydCourtpA6JLEYupT7ZUQ34hLfQZfRN5H47zLdz#z6LSrzxMVydCourtpA6JLEYupT7ZUQ34hLfQZfRN5H47zLdz",
|
|
||||||
"type": "JsonWebKey2020",
|
|
||||||
"controller": "did:key:z6LSrzxMVydCourtpA6JLEYupT7ZUQ34hLfQZfRN5H47zLdz",
|
|
||||||
"publicKeyJwk": {
|
|
||||||
"kty": "OKP",
|
|
||||||
"crv": "X25519",
|
|
||||||
"x": "467ap28wHJGEXJAb4mLrokqq8A-txA_KmoQTcj31XzU"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"keyAgreement": [
|
|
||||||
"did:key:z6LSrzxMVydCourtpA6JLEYupT7ZUQ34hLfQZfRN5H47zLdz#z6LSrzxMVydCourtpA6JLEYupT7ZUQ34hLfQZfRN5H47zLdz"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
37
go.mod
37
go.mod
@@ -1,42 +1,35 @@
|
|||||||
module github.com/ucan-wg/go-ucan
|
module code.sonr.org/go/ucan
|
||||||
|
|
||||||
go 1.23
|
go 1.24.4
|
||||||
|
|
||||||
|
toolchain go1.24.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0
|
code.sonr.org/go/did-it v1.0.0
|
||||||
github.com/ipfs/go-cid v0.4.1
|
github.com/avast/retry-go/v4 v4.6.1
|
||||||
|
github.com/ipfs/go-cid v0.5.0
|
||||||
github.com/ipld/go-ipld-prime v0.21.0
|
github.com/ipld/go-ipld-prime v0.21.0
|
||||||
github.com/lestrrat-go/jwx/v2 v2.1.1
|
|
||||||
github.com/libp2p/go-libp2p v0.36.3
|
|
||||||
github.com/mr-tron/base58 v1.2.0
|
|
||||||
github.com/multiformats/go-multibase v0.2.0
|
github.com/multiformats/go-multibase v0.2.0
|
||||||
github.com/multiformats/go-multicodec v0.9.0
|
github.com/multiformats/go-multicodec v0.9.0
|
||||||
github.com/multiformats/go-multihash v0.2.3
|
github.com/multiformats/go-multihash v0.2.3
|
||||||
github.com/multiformats/go-varint v0.0.7
|
github.com/multiformats/go-varint v0.1.0
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.10.0
|
||||||
gotest.tools/v3 v3.5.1
|
github.com/ucan-wg/go-varsig v1.0.0
|
||||||
|
golang.org/x/crypto v0.45.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/goccy/go-json v0.10.3 // indirect
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
|
||||||
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
|
|
||||||
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
|
||||||
github.com/lestrrat-go/httprc v1.0.6 // indirect
|
|
||||||
github.com/lestrrat-go/iter v1.0.2 // indirect
|
|
||||||
github.com/lestrrat-go/option v1.0.1 // indirect
|
|
||||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||||
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
github.com/multiformats/go-base32 v0.1.0 // indirect
|
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||||
github.com/multiformats/go-base36 v0.2.0 // indirect
|
github.com/multiformats/go-base36 v0.2.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/polydawn/refmt v0.89.0 // indirect
|
github.com/polydawn/refmt v0.89.0 // indirect
|
||||||
github.com/segmentio/asm v1.2.0 // indirect
|
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
golang.org/x/crypto v0.25.0 // indirect
|
golang.org/x/sys v0.38.0 // indirect
|
||||||
golang.org/x/sys v0.22.0 // indirect
|
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
lukechampine.com/blake3 v1.3.0 // indirect
|
lukechampine.com/blake3 v1.3.0 // indirect
|
||||||
|
|||||||
72
go.sum
72
go.sum
@@ -1,49 +1,34 @@
|
|||||||
|
code.sonr.org/go/did-it v1.0.0 h1:Wh8igUkD6cuf0Ul3gawi27z2/M1YfdnQ/mD9gBq/2EU=
|
||||||
|
code.sonr.org/go/did-it v1.0.0/go.mod h1:PFK6ItvNyB2xbnVqipBbkN9BK1Sq+E2lf1YfOyCA0Og=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk=
|
||||||
|
github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
|
github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg=
|
||||||
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
|
github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk=
|
||||||
github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E=
|
github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E=
|
||||||
github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ=
|
github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
|
|
||||||
github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
|
|
||||||
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
|
|
||||||
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
|
|
||||||
github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k=
|
|
||||||
github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
|
|
||||||
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
|
|
||||||
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
|
|
||||||
github.com/lestrrat-go/jwx/v2 v2.1.1 h1:Y2ltVl8J6izLYFs54BVcpXLv5msSW4o8eXwnzZLI32E=
|
|
||||||
github.com/lestrrat-go/jwx/v2 v2.1.1/go.mod h1:4LvZg7oxu6Q5VJwn7Mk/UwooNRnTHUpXBj2C4j3HNx0=
|
|
||||||
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
|
|
||||||
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
|
||||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
|
||||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
|
||||||
github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ=
|
|
||||||
github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8=
|
|
||||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||||
@@ -52,16 +37,14 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG
|
|||||||
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
||||||
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||||
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||||
github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ=
|
|
||||||
github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
|
|
||||||
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||||
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
||||||
github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=
|
github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=
|
||||||
github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
|
github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
|
||||||
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
||||||
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
||||||
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
github.com/multiformats/go-varint v0.1.0 h1:i2wqFp4sdl3IcIxfAonHQV9qU5OsZ4Ts9IOoETFs5dI=
|
||||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
github.com/multiformats/go-varint v0.1.0/go.mod h1:5KVAVXegtfmNQQm/lCY+ATvDzvJJhSkUlGQV9wgObdI=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4=
|
github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4=
|
||||||
@@ -69,8 +52,6 @@ github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX
|
|||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
|
||||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
|
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
|
||||||
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||||
@@ -78,38 +59,29 @@ github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hg
|
|||||||
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
|
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
|
||||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/ucan-wg/go-varsig v1.0.0 h1:Hrc437Zg+B5Eoajg+qZQZI3Q3ocPyjlnp3/Bz9ZnlWw=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/ucan-wg/go-varsig v1.0.0/go.mod h1:Sakln6IPooDPH+ClQ0VvR09TuwUhHcfLqcPiPkMZGh0=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
||||||
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
|
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
|
||||||
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
|
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
|
||||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
|
||||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
|
||||||
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
|
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
|
||||||
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime/node/basicnode"
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
||||||
"github.com/ipld/go-ipld-prime/printer"
|
"github.com/ipld/go-ipld-prime/printer"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/limits"
|
"code.sonr.org/go/ucan/pkg/policy/limits"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
"code.sonr.org/go/ucan/pkg/policy/literal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrNotFound = errors.New("key not found in meta")
|
var ErrNotFound = errors.New("key not found in meta")
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/args"
|
"code.sonr.org/go/ucan/pkg/args"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/limits"
|
"code.sonr.org/go/ucan/pkg/policy/limits"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
"code.sonr.org/go/ucan/pkg/policy/literal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestArgs(t *testing.T) {
|
func TestArgs(t *testing.T) {
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/args"
|
|
||||||
|
"code.sonr.org/go/ucan/pkg/args"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBuilder_XXX(t *testing.T) {
|
func TestBuilder_XXX(t *testing.T) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/command"
|
"code.sonr.org/go/ucan/pkg/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTop(t *testing.T) {
|
func TestTop(t *testing.T) {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# Token container
|
# Token container
|
||||||
|
|
||||||
|
The specification has been promoted to https://github.com/ucan-wg/container.
|
||||||
|
|
||||||
## Why do I need that?
|
## Why do I need that?
|
||||||
|
|
||||||
Some common situation asks to package multiple tokens together:
|
Some common situation asks to package multiple tokens together:
|
||||||
|
|||||||
1
pkg/container/containertest/Base64StdPadding
Normal file
1
pkg/container/containertest/Base64StdPadding
Normal file
File diff suppressed because one or more lines are too long
1
pkg/container/containertest/Base64StdPaddingGzipped
Normal file
1
pkg/container/containertest/Base64StdPaddingGzipped
Normal file
@@ -0,0 +1 @@
|
|||||||
|
OH4sIAAAAAAAA/5zXa5MU1R3HcXYjIOAVMQZQUQElCGx3n9M3wLhzn8xl3ZnpuSLB0+ecnp6enft9VBJWjSAkxEVXkBUJAgbULTUq4gULlWhQiauilKiFgiaFoIhoCVFIpXY3VXm2s2/g++RTv+7/+bOGi+nZZfauaNOGzkgrmfzUPZ9cOm50aPP2jdPmvbb81I3vbtiTWHDmwAcZZt+W78+6vCU3Irb6u23LjnR37vp07d5Iz7nHX9+96OnXlsw8e9Oaj87agHQnbDradLTpolyhhFG6hXTEW9k5zBxmdh7PYf+CUYlUJZIgc5O0NrcueJOJrDlsLkKXwBnEYlciBgsAWyqFgdnpy6oxPWU3SCpQE0L+KI9xiugtWibToqI8ptXsJL2rZRtOFAr/3yxqAQfJqG6iS6561FqQsk7ZkecUt9cac9WSpOSGJb9d9njNsIqzmY4lt2HU0YHnLFh4G/qVNqeMOkq0GRdK6vCzJEWL6CFdALzMsQIyEAZUYjlW0nRJJAwPNN5QBY3lAAC8oKuYUsLKqqFRAau8RgGl6UwaU891vofXTUn5Lu58ZDzpRzqlf63e713VHbzpqg8X3iqFfzniqfGtdlx7DrzQfPbDT2RXHLnnX9e/fLJp/eFR27974d9/3HHJyusXt7+Zcoyd9uIPSzePGAZSho/biynJrhC3JrEIFeSUkOc9rmSbwWqlMKl5Wc2d5kRUz1iGjOTLxLwatBZVv9tdkWFIoylbDvjsjjbOXSt7JFhkXVQgBS5ZagSpgewAEkcYqFHAGSojIEJEyCNdFjmMoUoNBjEyIBJhNR0JjEQIkQ1WhiJCSMBkAMl427RzzztvjD8G9jP9SONm9dxw6dFNH78+uqfpgtRV3ZEfJ3jfbfvkw0MLr/J2r205cGjrvOVvdNaa4tPO7GpfMWXU12+8N4ELOK/tu2DJzrc7rztnGEglu0VM521lPl0LmqOuhBRMZ/KC1ahYRXdSUax5bM9nqlRtJ5nKUJFyLjtvMoMyF0yaCvlE0mGLI1MkAKGlFOAEEiaKOx0qUls4YKo3gNRIdgBJpIwIJcgaUCaaJmkaILosaAQLEm8IkgiIpAmY0xECDFUhNhCUiCxzGGgDSIuv+WnPyHPyh1f3XRDuR/p2VXRu29o7XKfEVTN6F/kfv2XLyyfI7vWT+27+NvDZoZk3L7jm+Jm3Os9qPbjd0/fNHdmtTcKnnfKMpnVLf977PTjw2djhfO7CAQLNKFVS89GU325j0/ZcO0ybc+4QnyhhUfTasSoVK1aHxxgqklZIB+yYOjhUZWvRrNNVjqlK1iFUTTZTwFOLpMopW6ZYyeZ03t8AUiPZwSVJjIoAgwxNBSzlOVVWdaRJVOAwMgQKMKQSFXmdcARSEUkGFVUWS4IApAGkhyb+bPHD1yg3jHt1m9KP1D7Z81H2oxu/WEaZY5NOPtrT8fQGafFXc2/7HNw+4q5/2vnn9yJ2zIQFm8907niQ+eKbg9Gde73li/RJnv3dpmV/rY8cBpKRC1lNpmBBL/uSFVd7RkplEuFSOJRzJ4rZTCwlxnRLu9RWZKNCdqhImbBIY6Ag2CxqWrbFcrYsiXj8SibSHpDEWtRjCmeor8x6VL8oNYDUSHZwSVDGEuVYQxR5ATAaAZqu8ghSGQGDhRLAgOVkrGPK8xLPA0OgqkqoIKqDS1o/ZdHt7ldffNPyt3un9yPN+MU73vKTuw8F1z17+fe+51Yefn+s5+rz1t0Fn36m9akHz7viifvOXV1r//KVWRvbn22euGD9LPjK3d0FX2zTe4vgyMuOjRsGkibmcKCuhMPhesxQirLVAkvAEtUDvmilYI5EjIALAIGIfCwcHfKSUgVH0JZJKW2yFpFs2GKEzdlstaLkk0otmw6l7YYt68rURDGXa2RJDWQHkJj/fus4jTeoTCiUACMLOsuyLIepZlABUchCIEm6jCmLeYE3VKgyPOE1QR1Amsif2hd9xD//84nTf92PVDgynzy//f4Pbthd2fXV6dZXxl7bd1oYX7LN61o7f/TyS0bfd2Tes4ww76Y9S5ofK+y7+bONZ59/ZzI/6qLN+49dvX7mlObhHA5Wtz9ZTHJVZ8hU8lS5rN+XUarhUpuiQFeUr+QqcrBsWKyBSMQ0VKR4oEYdqbqYj8slrlyzSL6YyezWqZoTSDgcr5hqCleL1jTBldUbQGokO4gkEkGDCBuiJsssAJKGdEEVMRUhMVRKOVZlBRHoIoZAZBneIAyrchpiODyA9OBLv5tv77LPvqK+98p+pMyOH1b2jFrW+vfukx1XjlkxsnjnNPWdW3t63dHO5nMegCO37Np74uSkNZ7I0i1be0949RWt5y/v/P29k17auiZ0r/PCYS0pqoZ8ArZhD1EVn+IuakF/LOV3hi1WSYmgSDEfzJjSrhCXrg75BE9mcEGwu4uGWrRWg1az3aaLDo56QnWTJeJ3pKqRUnsorNkKXgQaQGokO4DEU5lqiFCDZ6jGMzIiSBcow/EaRw3IExYQwkFGxwKHJIGTDBkwGtIAwoMn+CfL7+77urfL/UxtwS39SH+6sGvR/M3b7j489vTU1OwxHxxnp7rWHVx98fpL9ph/M/fEq1ue+e1N/xDGNz9xCzw8q3vyZT2jp46ePuP9mZvqo/bv+6llOP+kuMfscECbC5eddZJTfHlT2M5bk4GEYvWZS3mxElTCKdkUS8XjcMjXHUtLCaermiY4S2g8zpoiRqIcssplwuUlECoqeiXutikRACONXHcNZAeXpKqCqMmcgURW1lgsAUkHkGUxo6kGhYSIEksg0mXACEjloAGhCmRVZoXBJS2LGo9+PG7/LrnvXXc/0iOu5JnKZS0/9n65Za8n+d3jdfGtx5ZEVtktu9uPT1+9Z8J2T8fGrulTS5mltvn3H+xyHljjfODJHWt3LkycGfOYDYwaBlLF7ra4goKzXg2zyJXysnwlTKS8I2su5R12iiqkXKon4gb0ytyQ30nBONtWymUrZU/cUi9DLppTvJZglavadJxyF5N2wSSBkDNiVWONvJMayP5vSURSkcAYLBYBx0CEVF0SoarxSDQIzyFGRZJMdY2DHBEk2ZA5RmU4BjBwAOlopu2+lb0heeXJP9zxnwAAAP//V8QWnXsQAAA=
|
||||||
1
pkg/container/containertest/Base64URL
Normal file
1
pkg/container/containertest/Base64URL
Normal file
File diff suppressed because one or more lines are too long
1
pkg/container/containertest/Base64URLGzipped
Normal file
1
pkg/container/containertest/Base64URLGzipped
Normal file
@@ -0,0 +1 @@
|
|||||||
|
PH4sIAAAAAAAA_5zW65MU1f3HcS7-hB8igpfIgqUxCqLC0tfTfUADMzs7M87ObubaOzMEsM-lp6eb6Zmee49GvEKwVBQRgygIUVHLCwoqoJAAikCQaJRICCqFGPCCcXVFoaBMJbukKs929h94P3nV-ZzvSg2XrEkV9u7kwFW3J6bv7bj7tflfrjm4e8_grc7Dke4jPx6c_Mm87olH_O9Of35_59-X7z2xe056dKx7156F074aOXzCcemCRe-Y4T3n3v7SNV-fdd4qVfcLA48NPDbwArtYxqo1mcxJT2ebmWZmUgE3s09jtUxqMsmQKSZ1ptRBu5lF0WK75ZbawpVO25NW2rLtfgG5XFZKtlwBr1GPVfyKU9YjZS_BOEv0yVouNxmpBUxr-TH6osmv4Uyx-L9NM5PUWqLtmqTohbQnkWp1i5JlxiOWLxAFAdaJeU13Z0gwWsN2AOdzc267A6tz5uDmGTPvUH-pNVfUOWU6CBfLqP9ZkqUl9fc6w3KqRmTVUDWGB1BiiKoDCBhJptRABAuCxrJY0zHPQBZjbLCY8hKCVBOplbMwDXbdsO9O4ZT5m20fTPywBymh3HfTBjDl5MzlT65xpm15kC4-f_2hlTtKyQUbrj78wBPfjn1e3T9i7OmuEfmt25d4z_q2K_0H36lRiw_9NbK0Szy0d3A_kPKuFk6qOYqVTSCj2uGNknxdT0BN0Etlqklxr8QaSqzF468oQl-R0oo7rztKQaK5crqzmMq7vOV4uh4jFZ2zPIrfFL0hS_ZYOFikDSA1ku1FAqJEZIRUA2gMy0OeY4EOKGVlHmCDIgZKKhYhp2NKGQR5YvBYZAWVp4j0Io1b4N905xU_e_SJj1-4pAfpbefa207fnMit_9XP39xxw7D3Fk0bH7vs09W_3uwcG3Vk5Nxv14yYP2Zj7lLPQ01Nnw0bsmXTssuZprL6-dX3zB3U9NH9q8_tB1KhgwUG8gA54HH5OcMyW1vqjmLnO11GNB0Ph6ut8WI1zAbdSMv2FclKhWK2riCS9trFvDvmd3tC0bpo8SAeC5QExZfiO3LeIOuKePkGkBrJnkEiWJYlnjEg1nhERSKouowIUgEvGUTGRBN5Ims6QiyVZVUwNIp4GUNOxr1I199x4OH_y6103Q-3DOhBuhYw1x1Y9eHYjejREfahp2Z9SNaqo83Xb0yff-mFr3_srFg7at3FV2aEy28atv2p8zbc-313YOQ3y65gm1Z9MHzdipHm0H4gFYmaLrQGWjpFLp4ICmagamWKHI560tlAsoa1uNcotoQKWj7fGuvz3Ck1v5hJgvZQJGYIKTlcFrypWocVLHPuEC_oWa2e0M3OVsen-BuZuwayZ-YOckQARDJ4TLAsChqUdVHVOBkA1pA5GVKGkaiqA04CDISiIcoUMhRjCHuRmjJraxO7f_ji-PiTE3pf0g83F4Zc-hF4-7uTV4XPG7xw986TC__2_qlnjrf9OLDrrKfeXioPGvtN0-NHRv8OHh7_5fzP1V3Lt40Zar-z-c3Vtx5O54b0AykTCrGsVS1iKmkdapQ1q6lqKWkV2gD1J3MIY09SlHw5O6yHgn1FqnoTLU66YobsbASoKq46rmoka2c8LomNkHBFYH2VVldNa-GTQgNIjWR7kTiVAIYRsYEFTcMCgpDqogw4TFXGwKqmYaACRtMJ4ClmEDAQFaHAYAbSXqRXxt9z8fIVxXOXjpjI9SDtXIkK6MJ3T6xbv-WuN7azi9K8UGl5a1t056x9G6fgxJJ5g03lSBk_O2juXV0Lnh2kVHfIwcqrKw-9dboId5X-eU5__iRPLhyxMsF03C9ZnWYKtRfZajIbUDjb68k7XFG2UL5adKesKOwrku42qkgrRaK2lI1jYJaMelnpaLf9RhW0sfmUrjk-FymaAcHBDSA1ku1FYjVeBBpGBqUCpjIUKdI5TuAwwqqhiQAAyvAQ6BoDBCgiwSCizMsSQhzfi_SP-2K_-PGE9saxTzMze5Dy-z0P7Di679olRys3fzdIXbZgbpvy0Krm5oXnnP_1w9yzj0yF8_64bCjzW2H22feEv48NLk6_8UD32fWPNvlf_CS18OUB_UDSE1WcaNUKSsqx_SjA-zNeLYI4T0cybfM4pbMg4AknnbbOetjqK1K-blcKUt4DWcNrVBzBIiJ2fGE7W8gCKZbI4WhBy4KkP9MWhA0gNZL9LxJLVMQhA_KEkTAjEkbnBZFILMQGQRLPi5gSpAOqEShqqoFFWZA4jCHoRRLeO9XcMqtwy7p35cd6kIY99snirRBtnvqcHN9benz4hCuG3LJt9bafZki7thTP_mHpi5PGXfbY6N1Nm68Z992tLD51S-q5DR98dsnhAbNSNzwZvOr_-4FUTdpy0XIjlg0nZSHkqaneUBVUCylgZEtmwQ3LhZrhR3WtkrX7PHegSpISVKtKuCYFyu11s5pK6FHbR112BNtsIZUOt1fSHVIuLzYydw1kz8ydoGqUF4nBizIHZYFyog5ZLHCU0QwEOZGROVEiusr824blDCgBSSIMgGdO8ClPP7KYPJnsQIeKG3uQrnz5teFvvD98hrrOc3nrmK3rn9s_-09PjBzaddOwxDl3Hz1xfEx810uPhvYcbL3sL9dNWjnuxamjXnCFEheAP29i5nXf3tGf6y7r6qwrJZfHlLyGLCvuWCf05Qp6JGDYBaNWqnvS5bKN_VRBVaWvSDnJBG4lHBEAl05yIccVIHZabmmLBttdobSjaKY3FRY9alvY42oAqZFsL5KKCAaEQkMlokgpyzKijhlRpaIoGZClCLCU1ahOIGQhFWSDQwLLqkhlzrwkvOH-ScEtSw68Omr87B6kpYWRa185WbvuC8u8aMC0i1pXbHeO72P9982fsHhh2xbf8WGe0y5Zq-wAk3YenZ05evG93MzVAx78aXJlxr1r2hce7A9Srqh6jIIVjNU7INENUg7Tqmz7tFBb2pfy-oq6zxuOOO0kWo27-3yC58tCwi900DxOtpk-k2txFCfuCGKllnOscqVk-W0N1dmoFcw3coI3kO1FElVWYhiiGhzgCS-xPES6zFKVAZxgyIAXJZWjAOsygppAEG_8Z-wIQZzai7Ri5eyp3V8981nL9fET_woAAP__svLMp3sQAAA
|
||||||
BIN
pkg/container/containertest/Bytes
Normal file
BIN
pkg/container/containertest/Bytes
Normal file
Binary file not shown.
BIN
pkg/container/containertest/BytesGzipped
Normal file
BIN
pkg/container/containertest/BytesGzipped
Normal file
Binary file not shown.
21
pkg/container/containertest/containertest.go
Normal file
21
pkg/container/containertest/containertest.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package containertest
|
||||||
|
|
||||||
|
import _ "embed"
|
||||||
|
|
||||||
|
//go:embed Base64StdPadding
|
||||||
|
var Base64StdPadding string
|
||||||
|
|
||||||
|
//go:embed Base64StdPaddingGzipped
|
||||||
|
var Base64StdPaddingGzipped string
|
||||||
|
|
||||||
|
//go:embed Base64URL
|
||||||
|
var Base64URL string
|
||||||
|
|
||||||
|
//go:embed Base64URLGzipped
|
||||||
|
var Base64URLGzipped string
|
||||||
|
|
||||||
|
//go:embed Bytes
|
||||||
|
var Bytes []byte
|
||||||
|
|
||||||
|
//go:embed BytesGzipped
|
||||||
|
var BytesGzipped []byte
|
||||||
118
pkg/container/packaging.go
Normal file
118
pkg/container/packaging.go
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"compress/gzip"
|
||||||
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const containerVersionTag = "ctn-v1"
|
||||||
|
|
||||||
|
type header byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
headerRawBytes = header(0x40)
|
||||||
|
headerBase64StdPadding = header(0x42)
|
||||||
|
headerBase64URL = header(0x43)
|
||||||
|
headerRawBytesGzip = header(0x4D)
|
||||||
|
headerBase64StdPaddingGzip = header(0x4F)
|
||||||
|
headerBase64URLGzip = header(0x50)
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h header) encoder(w io.Writer) *payloadWriter {
|
||||||
|
res := &payloadWriter{rawWriter: w, writer: w, header: h}
|
||||||
|
|
||||||
|
switch h {
|
||||||
|
case headerBase64StdPadding, headerBase64StdPaddingGzip:
|
||||||
|
b64Writer := base64.NewEncoder(base64.StdEncoding, res.writer)
|
||||||
|
res.writer = b64Writer
|
||||||
|
res.closers = append([]io.Closer{b64Writer}, res.closers...)
|
||||||
|
case headerBase64URL, headerBase64URLGzip:
|
||||||
|
b64Writer := base64.NewEncoder(base64.RawURLEncoding, res.writer)
|
||||||
|
res.writer = b64Writer
|
||||||
|
res.closers = append([]io.Closer{b64Writer}, res.closers...)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch h {
|
||||||
|
case headerRawBytesGzip, headerBase64StdPaddingGzip, headerBase64URLGzip:
|
||||||
|
gzipWriter := gzip.NewWriter(res.writer)
|
||||||
|
res.writer = gzipWriter
|
||||||
|
res.closers = append([]io.Closer{gzipWriter}, res.closers...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func payloadDecoder(r io.Reader) (io.Reader, error) {
|
||||||
|
headerBuf := make([]byte, 1)
|
||||||
|
_, err := r.Read(headerBuf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
h := header(headerBuf[0])
|
||||||
|
|
||||||
|
switch h {
|
||||||
|
case headerRawBytes,
|
||||||
|
headerBase64StdPadding,
|
||||||
|
headerBase64URL,
|
||||||
|
headerRawBytesGzip,
|
||||||
|
headerBase64StdPaddingGzip,
|
||||||
|
headerBase64URLGzip:
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown container header")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch h {
|
||||||
|
case headerBase64StdPadding, headerBase64StdPaddingGzip:
|
||||||
|
r = base64.NewDecoder(base64.StdEncoding, r)
|
||||||
|
case headerBase64URL, headerBase64URLGzip:
|
||||||
|
r = base64.NewDecoder(base64.RawURLEncoding, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch h {
|
||||||
|
case headerRawBytesGzip, headerBase64StdPaddingGzip, headerBase64URLGzip:
|
||||||
|
gzipReader, err := gzip.NewReader(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r = gzipReader
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ io.WriteCloser = &payloadWriter{}
|
||||||
|
|
||||||
|
// payloadWriter is tasked with two things:
|
||||||
|
// - prepend the header byte
|
||||||
|
// - call Close() on all the underlying io.Writer
|
||||||
|
type payloadWriter struct {
|
||||||
|
rawWriter io.Writer
|
||||||
|
writer io.Writer
|
||||||
|
header header
|
||||||
|
headerWrote bool
|
||||||
|
closers []io.Closer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *payloadWriter) Write(p []byte) (n int, err error) {
|
||||||
|
if !w.headerWrote {
|
||||||
|
_, err := w.rawWriter.Write([]byte{byte(w.header)})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
w.headerWrote = true
|
||||||
|
}
|
||||||
|
return w.writer.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *payloadWriter) Close() error {
|
||||||
|
var errs error
|
||||||
|
for _, closer := range w.closers {
|
||||||
|
if err := closer.Close(); err != nil {
|
||||||
|
errs = errors.Join(errs, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
@@ -2,8 +2,6 @@ package container
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"iter"
|
"iter"
|
||||||
@@ -11,98 +9,43 @@ import (
|
|||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
"github.com/ipld/go-ipld-prime/codec/cbor"
|
||||||
"github.com/ipld/go-ipld-prime/datamodel"
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/token"
|
"code.sonr.org/go/ucan/token"
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
"github.com/ucan-wg/go-ucan/token/invocation"
|
"code.sonr.org/go/ucan/token/invocation"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrNotFound = fmt.Errorf("not found")
|
var ErrNotFound = fmt.Errorf("not found")
|
||||||
var ErrMultipleInvocations = fmt.Errorf("multiple invocations")
|
var ErrMultipleInvocations = fmt.Errorf("multiple invocations")
|
||||||
|
|
||||||
// Reader is a token container reader. It exposes the tokens conveniently decoded.
|
// Reader is a token container reader. It exposes the tokens conveniently decoded.
|
||||||
type Reader map[cid.Cid]token.Token
|
type Reader map[cid.Cid]bundle
|
||||||
|
|
||||||
// GetToken returns an arbitrary decoded token, from its CID.
|
type bundle struct {
|
||||||
// If not found, ErrNotFound is returned.
|
sealed []byte
|
||||||
func (ctn Reader) GetToken(cid cid.Cid) (token.Token, error) {
|
token token.Token
|
||||||
tkn, ok := ctn[cid]
|
|
||||||
if !ok {
|
|
||||||
return nil, ErrNotFound
|
|
||||||
}
|
|
||||||
return tkn, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDelegation is the same as GetToken but only return a delegation.Token, with the right type.
|
// FromBytes decodes a container from a []byte
|
||||||
func (ctn Reader) GetDelegation(cid cid.Cid) (*delegation.Token, error) {
|
func FromBytes(data []byte) (Reader, error) {
|
||||||
tkn, err := ctn.GetToken(cid)
|
return FromReader(bytes.NewReader(data))
|
||||||
if errors.Is(err, ErrNotFound) {
|
|
||||||
return nil, delegation.ErrDelegationNotFound
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromString decodes a container from a string
|
||||||
|
func FromString(s string) (Reader, error) {
|
||||||
|
return FromReader(strings.NewReader(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromReader decodes a container from an io.Reader.
|
||||||
|
func FromReader(r io.Reader) (Reader, error) {
|
||||||
|
payload, err := payloadDecoder(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if tkn, ok := tkn.(*delegation.Token); ok {
|
|
||||||
return tkn, nil
|
|
||||||
}
|
|
||||||
return nil, delegation.ErrDelegationNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllDelegations returns all the delegation.Token in the container.
|
n, err := ipld.DecodeStreaming(payload, cbor.Decode)
|
||||||
func (ctn Reader) GetAllDelegations() iter.Seq2[cid.Cid, *delegation.Token] {
|
|
||||||
return func(yield func(cid.Cid, *delegation.Token) bool) {
|
|
||||||
for c, t := range ctn {
|
|
||||||
if t, ok := t.(*delegation.Token); ok {
|
|
||||||
if !yield(c, t) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInvocation returns a single invocation.Token.
|
|
||||||
// If none are found, ErrNotFound is returned.
|
|
||||||
// If more than one invocation exist, ErrMultipleInvocations is returned.
|
|
||||||
func (ctn Reader) GetInvocation() (*invocation.Token, error) {
|
|
||||||
var res *invocation.Token
|
|
||||||
for _, t := range ctn {
|
|
||||||
if inv, ok := t.(*invocation.Token); ok {
|
|
||||||
if res != nil {
|
|
||||||
return nil, ErrMultipleInvocations
|
|
||||||
}
|
|
||||||
res = inv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if res == nil {
|
|
||||||
return nil, ErrNotFound
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllInvocations returns all the invocation.Token in the container.
|
|
||||||
func (ctn Reader) GetAllInvocations() iter.Seq2[cid.Cid, *invocation.Token] {
|
|
||||||
return func(yield func(cid.Cid, *invocation.Token) bool) {
|
|
||||||
for c, t := range ctn {
|
|
||||||
if t, ok := t.(*invocation.Token); ok {
|
|
||||||
if !yield(c, t) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromCbor decodes a DAG-CBOR encoded container.
|
|
||||||
func FromCbor(data []byte) (Reader, error) {
|
|
||||||
return FromCborReader(bytes.NewReader(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromCborReader is the same as FromCbor, but with an io.Reader.
|
|
||||||
func FromCborReader(r io.Reader) (Reader, error) {
|
|
||||||
n, err := ipld.DecodeStreaming(r, dagcbor.Decode)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -124,7 +67,7 @@ func FromCborReader(r io.Reader) (Reader, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid container format: version must be string")
|
return nil, fmt.Errorf("invalid container format: version must be string")
|
||||||
}
|
}
|
||||||
if version != currentContainerVersion {
|
if version != containerVersionTag {
|
||||||
return nil, fmt.Errorf("unsupported container version: %s", version)
|
return nil, fmt.Errorf("unsupported container version: %s", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,52 +94,122 @@ func FromCborReader(r io.Reader) (Reader, error) {
|
|||||||
return ctn, nil
|
return ctn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromCborBase64 decodes a base64 DAG-CBOR encoded container.
|
// GetToken returns an arbitrary decoded token, from its CID.
|
||||||
func FromCborBase64(data string) (Reader, error) {
|
// If not found, ErrNotFound is returned.
|
||||||
return FromCborBase64Reader(strings.NewReader(data))
|
func (ctn Reader) GetToken(cid cid.Cid) (token.Token, error) {
|
||||||
|
bndl, ok := ctn[cid]
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrNotFound
|
||||||
|
}
|
||||||
|
return bndl.token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromCborBase64Reader is the same as FromCborBase64, but with an io.Reader.
|
// GetSealed returns an arbitrary sealed token, from its CID.
|
||||||
func FromCborBase64Reader(r io.Reader) (Reader, error) {
|
// If not found, ErrNotFound is returned.
|
||||||
return FromCborReader(base64.NewDecoder(base64.StdEncoding, r))
|
func (ctn Reader) GetSealed(cid cid.Cid) ([]byte, error) {
|
||||||
|
bndl, ok := ctn[cid]
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrNotFound
|
||||||
|
}
|
||||||
|
return bndl.sealed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromCar decodes a CAR file encoded container.
|
// GetAllTokens return all the tokens in the container.
|
||||||
func FromCar(data []byte) (Reader, error) {
|
func (ctn Reader) GetAllTokens() iter.Seq[token.Bundle] {
|
||||||
return FromCarReader(bytes.NewReader(data))
|
return func(yield func(token.Bundle) bool) {
|
||||||
|
for c, bndl := range ctn {
|
||||||
|
if !yield(token.Bundle{
|
||||||
|
Cid: c,
|
||||||
|
Decoded: bndl.token,
|
||||||
|
Sealed: bndl.sealed,
|
||||||
|
}) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromCarReader is the same as FromCar, but with an io.Reader.
|
|
||||||
func FromCarReader(r io.Reader) (Reader, error) {
|
|
||||||
_, it, err := readCar(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctn := make(Reader)
|
|
||||||
|
|
||||||
for block, err := range it {
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ctn.addToken(block.data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctn, nil
|
// GetDelegation is the same as GetToken but only return a delegation.Token, with the right type.
|
||||||
|
// If not found, delegation.ErrDelegationNotFound is returned.
|
||||||
|
func (ctn Reader) GetDelegation(cid cid.Cid) (*delegation.Token, error) {
|
||||||
|
tkn, err := ctn.GetToken(cid)
|
||||||
|
if err != nil { // only ErrNotFound expected
|
||||||
|
return nil, delegation.ErrDelegationNotFound
|
||||||
|
}
|
||||||
|
if tkn, ok := tkn.(*delegation.Token); ok {
|
||||||
|
return tkn, nil
|
||||||
|
}
|
||||||
|
return nil, delegation.ErrDelegationNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromCarBase64 decodes a base64 CAR file encoded container.
|
// GetDelegationBundle is the same as GetToken but only return a delegation.Bundle, with the right type.
|
||||||
func FromCarBase64(data string) (Reader, error) {
|
// If not found, delegation.ErrDelegationNotFound is returned.
|
||||||
return FromCarReader(strings.NewReader(data))
|
func (ctn Reader) GetDelegationBundle(cid cid.Cid) (*delegation.Bundle, error) {
|
||||||
|
bndl, ok := ctn[cid]
|
||||||
|
if !ok {
|
||||||
|
return nil, delegation.ErrDelegationNotFound
|
||||||
|
}
|
||||||
|
if tkn, ok := bndl.token.(*delegation.Token); ok {
|
||||||
|
return &delegation.Bundle{
|
||||||
|
Cid: cid,
|
||||||
|
Decoded: tkn,
|
||||||
|
Sealed: bndl.sealed,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, delegation.ErrDelegationNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromCarBase64Reader is the same as FromCarBase64, but with an io.Reader.
|
// GetAllDelegations returns all the delegation.Token in the container.
|
||||||
func FromCarBase64Reader(r io.Reader) (Reader, error) {
|
func (ctn Reader) GetAllDelegations() iter.Seq[*delegation.Bundle] {
|
||||||
return FromCarReader(base64.NewDecoder(base64.StdEncoding, r))
|
return func(yield func(*delegation.Bundle) bool) {
|
||||||
|
for c, bndl := range ctn {
|
||||||
|
if t, ok := bndl.token.(*delegation.Token); ok {
|
||||||
|
if !yield(&delegation.Bundle{
|
||||||
|
Cid: c,
|
||||||
|
Decoded: t,
|
||||||
|
Sealed: bndl.sealed,
|
||||||
|
}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInvocation returns a single invocation.Token.
|
||||||
|
// If none are found, ErrNotFound is returned.
|
||||||
|
// If more than one invocation exists, ErrMultipleInvocations is returned.
|
||||||
|
func (ctn Reader) GetInvocation() (*invocation.Token, error) {
|
||||||
|
var res *invocation.Token
|
||||||
|
for _, bndl := range ctn {
|
||||||
|
if inv, ok := bndl.token.(*invocation.Token); ok {
|
||||||
|
if res != nil {
|
||||||
|
return nil, ErrMultipleInvocations
|
||||||
|
}
|
||||||
|
res = inv
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if res == nil {
|
||||||
|
return nil, ErrNotFound
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllInvocations returns all the invocation.Token in the container.
|
||||||
|
func (ctn Reader) GetAllInvocations() iter.Seq[invocation.Bundle] {
|
||||||
|
return func(yield func(invocation.Bundle) bool) {
|
||||||
|
for c, bndl := range ctn {
|
||||||
|
if t, ok := bndl.token.(*invocation.Token); ok {
|
||||||
|
if !yield(invocation.Bundle{
|
||||||
|
Cid: c,
|
||||||
|
Decoded: t,
|
||||||
|
Sealed: bndl.sealed,
|
||||||
|
}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctn Reader) addToken(data []byte) error {
|
func (ctn Reader) addToken(data []byte) error {
|
||||||
@@ -204,6 +217,19 @@ func (ctn Reader) addToken(data []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ctn[c] = tkn
|
ctn[c] = bundle{
|
||||||
|
sealed: data,
|
||||||
|
token: tkn,
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToWriter convert a container Reader into a Writer.
|
||||||
|
// Most likely, you only want to use this in tests for convenience.
|
||||||
|
func (ctn Reader) ToWriter() Writer {
|
||||||
|
writer := NewWriter()
|
||||||
|
for _, bndl := range ctn {
|
||||||
|
writer.AddSealed(bndl.sealed)
|
||||||
|
}
|
||||||
|
return writer
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,27 +9,36 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it"
|
||||||
|
"code.sonr.org/go/did-it/controller/did-key"
|
||||||
|
"code.sonr.org/go/did-it/crypto/ed25519"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did"
|
"code.sonr.org/go/ucan/pkg/command"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/command"
|
"code.sonr.org/go/ucan/pkg/policy"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy"
|
"code.sonr.org/go/ucan/pkg/policy/literal"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContainerRoundTrip(t *testing.T) {
|
func TestContainerRoundTrip(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
writer func(ctn Writer, w io.Writer) error
|
expectedHeader header
|
||||||
reader func(io.Reader) (Reader, error)
|
writer any
|
||||||
}{
|
}{
|
||||||
{"car", Writer.ToCarWriter, FromCarReader},
|
{"Bytes", headerRawBytes, Writer.ToBytes},
|
||||||
{"carBase64", Writer.ToCarBase64Writer, FromCarBase64Reader},
|
{"BytesWriter", headerRawBytes, Writer.ToBytesWriter},
|
||||||
{"cbor", Writer.ToCborWriter, FromCborReader},
|
{"BytesGzipped", headerRawBytesGzip, Writer.ToBytesGzipped},
|
||||||
{"cborBase64", Writer.ToCborBase64Writer, FromCborBase64Reader},
|
{"BytesGzippedWriter", headerRawBytesGzip, Writer.ToBytesGzippedWriter},
|
||||||
|
{"Base64StdPadding", headerBase64StdPadding, Writer.ToBase64StdPadding},
|
||||||
|
{"Base64StdPaddingWriter", headerBase64StdPadding, Writer.ToBase64StdPaddingWriter},
|
||||||
|
{"Base64StdPaddingGzipped", headerBase64StdPaddingGzip, Writer.ToBase64StdPaddingGzipped},
|
||||||
|
{"Base64StdPaddingGzippedWriter", headerBase64StdPaddingGzip, Writer.ToBase64StdPaddingGzippedWriter},
|
||||||
|
{"Base64URL", headerBase64URL, Writer.ToBase64URL},
|
||||||
|
{"Base64URLWriter", headerBase64URL, Writer.ToBase64URLWriter},
|
||||||
|
{"Base64URLGzipped", headerBase64URLGzip, Writer.ToBase64URLGzipped},
|
||||||
|
{"Base64URLGzipWriter", headerBase64URLGzip, Writer.ToBase64URLGzipWriter},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
tokens := make(map[cid.Cid]*delegation.Token)
|
tokens := make(map[cid.Cid]*delegation.Token)
|
||||||
@@ -39,22 +48,54 @@ func TestContainerRoundTrip(t *testing.T) {
|
|||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
dlg, c, data := randToken()
|
dlg, c, data := randToken()
|
||||||
writer.AddSealed(c, data)
|
writer.AddSealed(data)
|
||||||
tokens[c] = dlg
|
tokens[c] = dlg
|
||||||
dataSize += len(data)
|
dataSize += len(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var reader Reader
|
||||||
|
var serialLen int
|
||||||
|
|
||||||
|
switch fn := tc.writer.(type) {
|
||||||
|
case func(ctn Writer, w io.Writer) error:
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
|
err := fn(writer, buf)
|
||||||
|
require.NoError(t, err)
|
||||||
|
serialLen = buf.Len()
|
||||||
|
|
||||||
err := tc.writer(writer, buf)
|
h, err := buf.ReadByte()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, byte(tc.expectedHeader), h)
|
||||||
|
err = buf.UnreadByte()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
t.Logf("data size %d", dataSize)
|
reader, err = FromReader(bytes.NewReader(buf.Bytes()))
|
||||||
t.Logf("container overhead: %d%%, %d bytes", int(float32(buf.Len()-dataSize)/float32(dataSize)*100.0), buf.Len()-dataSize)
|
|
||||||
|
|
||||||
reader, err := tc.reader(bytes.NewReader(buf.Bytes()))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
case func(ctn Writer) ([]byte, error):
|
||||||
|
b, err := fn(writer)
|
||||||
|
require.NoError(t, err)
|
||||||
|
serialLen = len(b)
|
||||||
|
|
||||||
|
require.Equal(t, byte(tc.expectedHeader), b[0])
|
||||||
|
|
||||||
|
reader, err = FromBytes(b)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
case func(ctn Writer) (string, error):
|
||||||
|
s, err := fn(writer)
|
||||||
|
require.NoError(t, err)
|
||||||
|
serialLen = len(s)
|
||||||
|
|
||||||
|
require.Equal(t, byte(tc.expectedHeader), s[0])
|
||||||
|
|
||||||
|
reader, err = FromString(s)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("data size %d, container size %d, overhead: %d%%, %d bytes",
|
||||||
|
dataSize, serialLen, int(float32(serialLen-dataSize)/float32(dataSize)*100.0), serialLen-dataSize)
|
||||||
|
|
||||||
for c, dlg := range tokens {
|
for c, dlg := range tokens {
|
||||||
tknRead, err := reader.GetToken(c)
|
tknRead, err := reader.GetToken(c)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -98,16 +139,18 @@ func BenchmarkContainerSerialisation(b *testing.B) {
|
|||||||
writer func(ctn Writer, w io.Writer) error
|
writer func(ctn Writer, w io.Writer) error
|
||||||
reader func(io.Reader) (Reader, error)
|
reader func(io.Reader) (Reader, error)
|
||||||
}{
|
}{
|
||||||
{"car", Writer.ToCarWriter, FromCarReader},
|
{"Bytes", Writer.ToBytesWriter, FromReader},
|
||||||
{"carBase64", Writer.ToCarBase64Writer, FromCarBase64Reader},
|
{"BytesGzipped", Writer.ToBytesGzippedWriter, FromReader},
|
||||||
{"cbor", Writer.ToCborWriter, FromCborReader},
|
{"Base64StdPadding", Writer.ToBase64StdPaddingWriter, FromReader},
|
||||||
{"cborBase64", Writer.ToCborBase64Writer, FromCborBase64Reader},
|
{"Base64StdPaddingGzipped", Writer.ToBase64StdPaddingGzippedWriter, FromReader},
|
||||||
|
{"Base64URL", Writer.ToBase64URLWriter, FromReader},
|
||||||
|
{"Base64URLGzip", Writer.ToBase64URLGzipWriter, FromReader},
|
||||||
} {
|
} {
|
||||||
writer := NewWriter()
|
writer := NewWriter()
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
_, c, data := randToken()
|
_, _, data := randToken()
|
||||||
writer.AddSealed(c, data)
|
writer.AddSealed(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
@@ -130,15 +173,12 @@ func BenchmarkContainerSerialisation(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func randDID() (crypto.PrivKey, did.DID) {
|
func randDID() (ed25519.PrivateKey, did.DID) {
|
||||||
privKey, _, err := crypto.GenerateEd25519Key(rand.Reader)
|
_, privKey, err := ed25519.GenerateKeyPair()
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
d, err := did.FromPrivKey(privKey)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
d := didkeyctl.FromPrivateKey(privKey)
|
||||||
return privKey, d
|
return privKey, d
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,10 +221,10 @@ func FuzzContainerRead(f *testing.F) {
|
|||||||
for tokenCount := 0; tokenCount < 10; tokenCount++ {
|
for tokenCount := 0; tokenCount < 10; tokenCount++ {
|
||||||
writer := NewWriter()
|
writer := NewWriter()
|
||||||
for i := 0; i < tokenCount; i++ {
|
for i := 0; i < tokenCount; i++ {
|
||||||
_, c, data := randToken()
|
_, _, data := randToken()
|
||||||
writer.AddSealed(c, data)
|
writer.AddSealed(data)
|
||||||
}
|
}
|
||||||
data, err := writer.ToCbor()
|
data, err := writer.ToBytes()
|
||||||
require.NoError(f, err)
|
require.NoError(f, err)
|
||||||
|
|
||||||
f.Add(data)
|
f.Add(data)
|
||||||
@@ -194,7 +234,7 @@ func FuzzContainerRead(f *testing.F) {
|
|||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
// search for panics
|
// search for panics
|
||||||
_, _ = FromCbor(data)
|
_, _ = FromBytes(data)
|
||||||
|
|
||||||
if time.Since(start) > 100*time.Millisecond {
|
if time.Since(start) > 100*time.Millisecond {
|
||||||
panic("too long")
|
panic("too long")
|
||||||
|
|||||||
@@ -2,46 +2,120 @@ package container
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
|
||||||
"io"
|
"io"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
"github.com/ipld/go-ipld-prime/codec/cbor"
|
||||||
"github.com/ipld/go-ipld-prime/datamodel"
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
"github.com/ipld/go-ipld-prime/fluent/qp"
|
"github.com/ipld/go-ipld-prime/fluent/qp"
|
||||||
"github.com/ipld/go-ipld-prime/node/basicnode"
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Writer is a token container writer. It provides a convenient way to aggregate and serialize tokens together.
|
// Writer is a token container writer. It provides a convenient way to aggregate and serialize tokens together.
|
||||||
type Writer map[cid.Cid][]byte
|
type Writer map[string]struct{}
|
||||||
|
|
||||||
func NewWriter() Writer {
|
func NewWriter() Writer {
|
||||||
return make(Writer)
|
return make(Writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddSealed includes a "sealed" token (serialized with a ToSealed* function) in the container.
|
// AddSealed includes a "sealed" token (serialized with a ToSealed* function) in the container.
|
||||||
func (ctn Writer) AddSealed(cid cid.Cid, data []byte) {
|
func (ctn Writer) AddSealed(data []byte) {
|
||||||
ctn[cid] = data
|
ctn[string(data)] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentContainerVersion = "ctn-v1"
|
// ToBytes encode the container into raw bytes.
|
||||||
|
func (ctn Writer) ToBytes() ([]byte, error) {
|
||||||
|
return ctn.toBytes(headerRawBytes)
|
||||||
|
}
|
||||||
|
|
||||||
// ToCbor encode the container into a DAG-CBOR binary format.
|
// ToBytesWriter is the same as ToBytes, but with an io.Writer.
|
||||||
func (ctn Writer) ToCbor() ([]byte, error) {
|
func (ctn Writer) ToBytesWriter(w io.Writer) error {
|
||||||
|
return ctn.toWriter(headerRawBytes, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBytesGzipped encode the container into gzipped bytes.
|
||||||
|
func (ctn Writer) ToBytesGzipped() ([]byte, error) {
|
||||||
|
return ctn.toBytes(headerRawBytesGzip)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBytesGzippedWriter is the same as ToBytesGzipped, but with an io.Writer.
|
||||||
|
func (ctn Writer) ToBytesGzippedWriter(w io.Writer) error {
|
||||||
|
return ctn.toWriter(headerRawBytesGzip, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBase64StdPadding encode the container into a base64 string, with standard encoding and padding.
|
||||||
|
func (ctn Writer) ToBase64StdPadding() (string, error) {
|
||||||
|
return ctn.toString(headerBase64StdPadding)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBase64StdPaddingWriter is the same as ToBase64StdPadding, but with an io.Writer.
|
||||||
|
func (ctn Writer) ToBase64StdPaddingWriter(w io.Writer) error {
|
||||||
|
return ctn.toWriter(headerBase64StdPadding, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBase64StdPaddingGzipped encode the container into a pre-gzipped base64 string, with standard encoding and padding.
|
||||||
|
func (ctn Writer) ToBase64StdPaddingGzipped() (string, error) {
|
||||||
|
return ctn.toString(headerBase64StdPaddingGzip)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBase64StdPaddingGzippedWriter is the same as ToBase64StdPaddingGzipped, but with an io.Writer.
|
||||||
|
func (ctn Writer) ToBase64StdPaddingGzippedWriter(w io.Writer) error {
|
||||||
|
return ctn.toWriter(headerBase64StdPaddingGzip, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBase64URL encode the container into base64 string, with URL-safe encoding and no padding.
|
||||||
|
func (ctn Writer) ToBase64URL() (string, error) {
|
||||||
|
return ctn.toString(headerBase64URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBase64URLWriter is the same as ToBase64URL, but with an io.Writer.
|
||||||
|
func (ctn Writer) ToBase64URLWriter(w io.Writer) error {
|
||||||
|
return ctn.toWriter(headerBase64URL, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBase64URLGzipped encode the container into pre-gzipped base64 string, with URL-safe encoding and no padding.
|
||||||
|
func (ctn Writer) ToBase64URLGzipped() (string, error) {
|
||||||
|
return ctn.toString(headerBase64URLGzip)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBase64URLGzipWriter is the same as ToBase64URL, but with an io.Writer.
|
||||||
|
func (ctn Writer) ToBase64URLGzipWriter(w io.Writer) error {
|
||||||
|
return ctn.toWriter(headerBase64URLGzip, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctn Writer) toBytes(header header) ([]byte, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err := ctn.ToCborWriter(&buf)
|
err := ctn.toWriter(header, &buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToCborWriter is the same as ToCbor, but with an io.Writer.
|
func (ctn Writer) toString(header header) (string, error) {
|
||||||
func (ctn Writer) ToCborWriter(w io.Writer) error {
|
var buf bytes.Buffer
|
||||||
|
err := ctn.toWriter(header, &buf)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctn Writer) toWriter(header header, w io.Writer) (err error) {
|
||||||
|
encoder := header.encoder(w)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err = encoder.Close()
|
||||||
|
}()
|
||||||
node, err := qp.BuildMap(basicnode.Prototype.Any, 1, func(ma datamodel.MapAssembler) {
|
node, err := qp.BuildMap(basicnode.Prototype.Any, 1, func(ma datamodel.MapAssembler) {
|
||||||
qp.MapEntry(ma, currentContainerVersion, qp.List(int64(len(ctn)), func(la datamodel.ListAssembler) {
|
qp.MapEntry(ma, containerVersionTag, qp.List(int64(len(ctn)), func(la datamodel.ListAssembler) {
|
||||||
for _, data := range ctn {
|
tokens := make([][]byte, 0, len(ctn))
|
||||||
|
for data := range ctn {
|
||||||
|
tokens = append(tokens, []byte(data))
|
||||||
|
}
|
||||||
|
slices.SortFunc(tokens, bytes.Compare)
|
||||||
|
for _, data := range tokens {
|
||||||
qp.ListEntry(la, qp.Bytes(data))
|
qp.ListEntry(la, qp.Bytes(data))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@@ -49,60 +123,23 @@ func (ctn Writer) ToCborWriter(w io.Writer) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ipld.EncodeStreaming(w, node, dagcbor.Encode)
|
|
||||||
|
return ipld.EncodeStreaming(encoder, node, cbor.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToCborBase64 encode the container into a base64 encoded DAG-CBOR binary format.
|
// ToReader convert a container Writer into a Reader.
|
||||||
func (ctn Writer) ToCborBase64() (string, error) {
|
// Most likely, you only want to use this in tests for convenience.
|
||||||
var buf bytes.Buffer
|
// This is not optimized and can panic.
|
||||||
err := ctn.ToCborBase64Writer(&buf)
|
func (ctn Writer) ToReader() Reader {
|
||||||
|
data, err := ctn.ToBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
panic(err)
|
||||||
}
|
|
||||||
return buf.String(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToCborBase64Writer is the same as ToCborBase64, but with an io.Writer.
|
reader, err := FromBytes(data)
|
||||||
func (ctn Writer) ToCborBase64Writer(w io.Writer) error {
|
|
||||||
w2 := base64.NewEncoder(base64.StdEncoding, w)
|
|
||||||
defer w2.Close()
|
|
||||||
return ctn.ToCborWriter(w2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToCar encode the container into a CAR file.
|
|
||||||
func (ctn Writer) ToCar() ([]byte, error) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := ctn.ToCarWriter(&buf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
panic(err)
|
||||||
}
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToCarWriter is the same as ToCar, but with an io.Writer.
|
return reader
|
||||||
func (ctn Writer) ToCarWriter(w io.Writer) error {
|
|
||||||
return writeCar(w, nil, func(yield func(carBlock, error) bool) {
|
|
||||||
for c, data := range ctn {
|
|
||||||
if !yield(carBlock{c: c, data: data}, nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToCarBase64 encode the container into a base64 encoded CAR file.
|
|
||||||
func (ctn Writer) ToCarBase64() (string, error) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := ctn.ToCarBase64Writer(&buf)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return buf.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToCarBase64Writer is the same as ToCarBase64, but with an io.Writer.
|
|
||||||
func (ctn Writer) ToCarBase64Writer(w io.Writer) error {
|
|
||||||
w2 := base64.NewEncoder(base64.StdEncoding, w)
|
|
||||||
defer w2.Close()
|
|
||||||
return ctn.ToCarWriter(w2)
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
pkg/container/writer_test.go
Normal file
18
pkg/container/writer_test.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWriterDedup(t *testing.T) {
|
||||||
|
ctn := NewWriter()
|
||||||
|
|
||||||
|
_, _, sealed := randToken()
|
||||||
|
ctn.AddSealed(sealed)
|
||||||
|
require.Len(t, ctn, 1)
|
||||||
|
|
||||||
|
ctn.AddSealed(sealed)
|
||||||
|
require.Len(t, ctn, 1)
|
||||||
|
}
|
||||||
@@ -10,8 +10,8 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/printer"
|
"github.com/ipld/go-ipld-prime/printer"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
"code.sonr.org/go/ucan/pkg/policy/literal"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/secretbox"
|
"code.sonr.org/go/ucan/pkg/secretbox"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrNotFound = errors.New("key not found in meta")
|
var ErrNotFound = errors.New("key not found in meta")
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime/node/basicnode"
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/meta"
|
"code.sonr.org/go/ucan/pkg/meta"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMeta_Add(t *testing.T) {
|
func TestMeta_Add(t *testing.T) {
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime/must"
|
"github.com/ipld/go-ipld-prime/must"
|
||||||
"github.com/ipld/go-ipld-prime/node/basicnode"
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/limits"
|
"code.sonr.org/go/ucan/pkg/policy/limits"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/selector"
|
"code.sonr.org/go/ucan/pkg/policy/selector"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FromIPLD(node datamodel.Node) (Policy, error) {
|
func FromIPLD(node datamodel.Node) (Policy, error) {
|
||||||
@@ -81,7 +81,7 @@ func statementFromIPLD(path string, node datamodel.Node) (Statement, error) {
|
|||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
switch op {
|
switch op {
|
||||||
case KindEqual, KindLessThan, KindLessThanOrEqual, KindGreaterThan, KindGreaterThanOrEqual:
|
case KindEqual, KindNotEqual, KindLessThan, KindLessThanOrEqual, KindGreaterThan, KindGreaterThanOrEqual:
|
||||||
sel, err := arg2AsSelector(op)
|
sel, err := arg2AsSelector(op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -21,10 +21,31 @@ func TestIpldRoundTrip(t *testing.T) {
|
|||||||
]
|
]
|
||||||
]`
|
]`
|
||||||
|
|
||||||
|
// must contain all the operators
|
||||||
|
const allOps = `
|
||||||
|
[
|
||||||
|
["and", [
|
||||||
|
["==", ".foo1", ".bar1"],
|
||||||
|
["!=", ".foo2", ".bar2"]
|
||||||
|
]],
|
||||||
|
["or", [
|
||||||
|
[">", ".foo5", 5.2],
|
||||||
|
[">=", ".foo6", 6.2]
|
||||||
|
]],
|
||||||
|
["not", ["like", ".foo7", "*@example.com"]],
|
||||||
|
["all", ".foo8",
|
||||||
|
["<", ".foo3", 3]
|
||||||
|
],
|
||||||
|
["any", ".foo9",
|
||||||
|
["<=", ".foo4", 4]
|
||||||
|
]
|
||||||
|
]`
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name, dagJsonStr string
|
name, dagJsonStr string
|
||||||
}{
|
}{
|
||||||
{"illustrativeExample", illustrativeExample},
|
{"illustrativeExample", illustrativeExample},
|
||||||
|
{"allOps", allOps},
|
||||||
} {
|
} {
|
||||||
nodes, err := ipld.Decode([]byte(tc.dagJsonStr), dagjson.Decode)
|
nodes, err := ipld.Decode([]byte(tc.dagJsonStr), dagjson.Decode)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// MaxInt53 represents the maximum safe integer in JavaScript (2^53 - 1)
|
// MaxInt53 represents the maximum safe integer in JavaScript (2^53 - 1)
|
||||||
MaxInt53 = 9007199254740991
|
MaxInt53 int64 = 9007199254740991
|
||||||
// MinInt53 represents the minimum safe integer in JavaScript (-2^53 + 1)
|
// MinInt53 represents the minimum safe integer in JavaScript (-2^53 + 1)
|
||||||
MinInt53 = -9007199254740991
|
MinInt53 int64 = -9007199254740991
|
||||||
)
|
)
|
||||||
|
|
||||||
func ValidateIntegerBoundsIPLD(node ipld.Node) error {
|
func ValidateIntegerBoundsIPLD(node ipld.Node) error {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
|
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
|
||||||
"github.com/ipld/go-ipld-prime/node/basicnode"
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/limits"
|
"code.sonr.org/go/ucan/pkg/policy/limits"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Bool = basicnode.NewBool
|
var Bool = basicnode.NewBool
|
||||||
@@ -185,7 +185,7 @@ func anyAssemble(val any) qp.Assemble {
|
|||||||
return qp.Int(i)
|
return qp.Int(i)
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
u := rv.Uint()
|
u := rv.Uint()
|
||||||
if u > limits.MaxInt53 {
|
if u > uint64(limits.MaxInt53) {
|
||||||
panic(fmt.Sprintf("unsigned integer %d exceeds safe bounds", u))
|
panic(fmt.Sprintf("unsigned integer %d exceeds safe bounds", u))
|
||||||
}
|
}
|
||||||
return qp.Int(int64(u))
|
return qp.Int(int64(u))
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime/printer"
|
"github.com/ipld/go-ipld-prime/printer"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/limits"
|
"code.sonr.org/go/ucan/pkg/policy/limits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestList(t *testing.T) {
|
func TestList(t *testing.T) {
|
||||||
|
|||||||
@@ -82,6 +82,17 @@ func matchStatement(cur Statement, node ipld.Node) (_ matchResult, leafMost Stat
|
|||||||
}
|
}
|
||||||
return boolToRes(datamodel.DeepEqual(s.value, res))
|
return boolToRes(datamodel.DeepEqual(s.value, res))
|
||||||
}
|
}
|
||||||
|
case KindNotEqual:
|
||||||
|
if s, ok := cur.(equality); ok {
|
||||||
|
res, err := s.selector.Select(node)
|
||||||
|
if err != nil {
|
||||||
|
return matchResultNoData, cur
|
||||||
|
}
|
||||||
|
if res == nil { // optional selector didn't match
|
||||||
|
return matchResultOptionalNoData, nil
|
||||||
|
}
|
||||||
|
return boolToRes(!datamodel.DeepEqual(s.value, res))
|
||||||
|
}
|
||||||
case KindGreaterThan:
|
case KindGreaterThan:
|
||||||
if s, ok := cur.(equality); ok {
|
if s, ok := cur.(equality); ok {
|
||||||
res, err := s.selector.Select(node)
|
res, err := s.selector.Select(node)
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime/node/basicnode"
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
"code.sonr.org/go/ucan/pkg/policy/literal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMatch(t *testing.T) {
|
func TestMatch(t *testing.T) {
|
||||||
t.Run("equality", func(t *testing.T) {
|
t.Run("equality", func(t *testing.T) {
|
||||||
t.Run("string", func(t *testing.T) {
|
t.Run("eq string", func(t *testing.T) {
|
||||||
nd := literal.String("test")
|
nd := literal.String("test")
|
||||||
|
|
||||||
pol := MustConstruct(Equal(".", literal.String("test")))
|
pol := MustConstruct(Equal(".", literal.String("test")))
|
||||||
@@ -35,7 +35,7 @@ func TestMatch(t *testing.T) {
|
|||||||
require.Equal(t, pol[0], leaf)
|
require.Equal(t, pol[0], leaf)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("int", func(t *testing.T) {
|
t.Run("eq int", func(t *testing.T) {
|
||||||
nd := literal.Int(138)
|
nd := literal.Int(138)
|
||||||
|
|
||||||
pol := MustConstruct(Equal(".", literal.Int(138)))
|
pol := MustConstruct(Equal(".", literal.Int(138)))
|
||||||
@@ -54,7 +54,7 @@ func TestMatch(t *testing.T) {
|
|||||||
require.Equal(t, pol[0], leaf)
|
require.Equal(t, pol[0], leaf)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("float", func(t *testing.T) {
|
t.Run("eq float", func(t *testing.T) {
|
||||||
nd := literal.Float(1.138)
|
nd := literal.Float(1.138)
|
||||||
|
|
||||||
pol := MustConstruct(Equal(".", literal.Float(1.138)))
|
pol := MustConstruct(Equal(".", literal.Float(1.138)))
|
||||||
@@ -73,7 +73,7 @@ func TestMatch(t *testing.T) {
|
|||||||
require.Equal(t, pol[0], leaf)
|
require.Equal(t, pol[0], leaf)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("IPLD Link", func(t *testing.T) {
|
t.Run("eq IPLD Link", func(t *testing.T) {
|
||||||
l0 := cidlink.Link{Cid: cid.MustParse("bafybeif4owy5gno5lwnixqm52rwqfodklf76hsetxdhffuxnplvijskzqq")}
|
l0 := cidlink.Link{Cid: cid.MustParse("bafybeif4owy5gno5lwnixqm52rwqfodklf76hsetxdhffuxnplvijskzqq")}
|
||||||
l1 := cidlink.Link{Cid: cid.MustParse("bafkreifau35r7vi37tvbvfy3hdwvgb4tlflqf7zcdzeujqcjk3rsphiwte")}
|
l1 := cidlink.Link{Cid: cid.MustParse("bafkreifau35r7vi37tvbvfy3hdwvgb4tlflqf7zcdzeujqcjk3rsphiwte")}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ func TestMatch(t *testing.T) {
|
|||||||
require.Equal(t, pol[0], leaf)
|
require.Equal(t, pol[0], leaf)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("string in map", func(t *testing.T) {
|
t.Run("eq string in map", func(t *testing.T) {
|
||||||
nd, _ := literal.Map(map[string]any{
|
nd, _ := literal.Map(map[string]any{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
})
|
})
|
||||||
@@ -121,7 +121,7 @@ func TestMatch(t *testing.T) {
|
|||||||
require.Equal(t, pol[0], leaf)
|
require.Equal(t, pol[0], leaf)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("string in list", func(t *testing.T) {
|
t.Run("eq string in list", func(t *testing.T) {
|
||||||
nd, _ := literal.List([]any{"foo"})
|
nd, _ := literal.List([]any{"foo"})
|
||||||
|
|
||||||
pol := MustConstruct(Equal(".[0]", literal.String("foo")))
|
pol := MustConstruct(Equal(".[0]", literal.String("foo")))
|
||||||
@@ -134,6 +134,132 @@ func TestMatch(t *testing.T) {
|
|||||||
require.False(t, ok)
|
require.False(t, ok)
|
||||||
require.Equal(t, pol[0], leaf)
|
require.Equal(t, pol[0], leaf)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("neq string", func(t *testing.T) {
|
||||||
|
nd := literal.String("test")
|
||||||
|
|
||||||
|
pol := MustConstruct(NotEqual(".", literal.String("test")))
|
||||||
|
ok, leaf := pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".", literal.String("test2")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".", literal.Int(138)))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("neq int", func(t *testing.T) {
|
||||||
|
nd := literal.Int(138)
|
||||||
|
|
||||||
|
pol := MustConstruct(NotEqual(".", literal.Int(138)))
|
||||||
|
ok, leaf := pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".", literal.Int(1138)))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".", literal.String("138")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("neq float", func(t *testing.T) {
|
||||||
|
nd := literal.Float(1.138)
|
||||||
|
|
||||||
|
pol := MustConstruct(NotEqual(".", literal.Float(1.138)))
|
||||||
|
ok, leaf := pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".", literal.Float(11.38)))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".", literal.String("138")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("neq IPLD Link", func(t *testing.T) {
|
||||||
|
l0 := cidlink.Link{Cid: cid.MustParse("bafybeif4owy5gno5lwnixqm52rwqfodklf76hsetxdhffuxnplvijskzqq")}
|
||||||
|
l1 := cidlink.Link{Cid: cid.MustParse("bafkreifau35r7vi37tvbvfy3hdwvgb4tlflqf7zcdzeujqcjk3rsphiwte")}
|
||||||
|
|
||||||
|
nd := literal.Link(l0)
|
||||||
|
|
||||||
|
pol := MustConstruct(NotEqual(".", literal.Link(l0)))
|
||||||
|
ok, leaf := pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".", literal.Link(l1)))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".", literal.String("bafybeif4owy5gno5lwnixqm52rwqfodklf76hsetxdhffuxnplvijskzqq")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("neq string in map", func(t *testing.T) {
|
||||||
|
nd, _ := literal.Map(map[string]any{
|
||||||
|
"foo": "bar",
|
||||||
|
})
|
||||||
|
|
||||||
|
pol := MustConstruct(NotEqual(".foo", literal.String("bar")))
|
||||||
|
ok, leaf := pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".[\"foo\"]", literal.String("bar")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".foo", literal.String("baz")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
|
||||||
|
// missing data will fail, as not optional
|
||||||
|
pol = MustConstruct(NotEqual(".foobar", literal.String("bar")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("neq string in list", func(t *testing.T) {
|
||||||
|
nd, _ := literal.List([]any{"foo"})
|
||||||
|
|
||||||
|
pol := MustConstruct(NotEqual(".[0]", literal.String("foo")))
|
||||||
|
ok, leaf := pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(NotEqual(".[0]", literal.String("bar")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
|
||||||
|
// missing data will fail, as not optional
|
||||||
|
pol = MustConstruct(NotEqual(".[1]", literal.String("foo")))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("inequality", func(t *testing.T) {
|
t.Run("inequality", func(t *testing.T) {
|
||||||
@@ -245,20 +371,61 @@ func TestMatch(t *testing.T) {
|
|||||||
require.False(t, ok)
|
require.False(t, ok)
|
||||||
require.Equal(t, pol[0], leaf)
|
require.Equal(t, pol[0], leaf)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("lt float", func(t *testing.T) {
|
||||||
|
nd := literal.Float(1.38)
|
||||||
|
|
||||||
|
pol := MustConstruct(LessThan(".", literal.Float(1)))
|
||||||
|
ok, leaf := pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(LessThan(".", literal.Float(2)))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("lte float", func(t *testing.T) {
|
||||||
|
nd := literal.Float(1.38)
|
||||||
|
|
||||||
|
pol := MustConstruct(LessThanOrEqual(".", literal.Float(1)))
|
||||||
|
ok, leaf := pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(GreaterThanOrEqual(".", literal.Float(1.38)))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
|
||||||
|
pol = MustConstruct(LessThanOrEqual(".", literal.Float(2)))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Nil(t, leaf)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("negation", func(t *testing.T) {
|
t.Run("negation", func(t *testing.T) {
|
||||||
nd := literal.Bool(false)
|
nd, _ := literal.Map(map[string]any{
|
||||||
|
"foo": false,
|
||||||
|
})
|
||||||
|
|
||||||
pol := MustConstruct(Not(Equal(".", literal.Bool(true))))
|
pol := MustConstruct(Not(Equal(".foo", literal.Bool(true))))
|
||||||
ok, leaf := pol.Match(nd)
|
ok, leaf := pol.Match(nd)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Nil(t, leaf)
|
require.Nil(t, leaf)
|
||||||
|
|
||||||
pol = MustConstruct(Not(Equal(".", literal.Bool(false))))
|
pol = MustConstruct(Not(Equal(".foo", literal.Bool(false))))
|
||||||
ok, leaf = pol.Match(nd)
|
ok, leaf = pol.Match(nd)
|
||||||
require.False(t, ok)
|
require.False(t, ok)
|
||||||
require.Equal(t, pol[0], leaf)
|
require.Equal(t, pol[0], leaf)
|
||||||
|
|
||||||
|
// missing data will fail, as not optional
|
||||||
|
pol = MustConstruct(Not(Equal(".foobar", literal.Bool(true))))
|
||||||
|
ok, leaf = pol.Match(nd)
|
||||||
|
require.False(t, ok)
|
||||||
|
require.Equal(t, MustConstruct(Equal(".foobar", literal.Bool(true)))[0], leaf)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("conjunction", func(t *testing.T) {
|
t.Run("conjunction", func(t *testing.T) {
|
||||||
@@ -482,6 +649,7 @@ func FuzzMatch(f *testing.F) {
|
|||||||
f.Add([]byte(`[["all", ".reviewer", ["like", ".email", "*@example.com"]]]`), []byte(`{"reviewer": [{"email": "alice@example.com"}, {"email": "bob@example.com"}]}`))
|
f.Add([]byte(`[["all", ".reviewer", ["like", ".email", "*@example.com"]]]`), []byte(`{"reviewer": [{"email": "alice@example.com"}, {"email": "bob@example.com"}]}`))
|
||||||
f.Add([]byte(`[["any", ".tags", ["or", [["==", ".", "news"], ["==", ".", "press"]]]]]`), []byte(`{"tags": ["news", "press"]}`))
|
f.Add([]byte(`[["any", ".tags", ["or", [["==", ".", "news"], ["==", ".", "press"]]]]]`), []byte(`{"tags": ["news", "press"]}`))
|
||||||
f.Add([]byte(`[["==", ".name", "Alice"]]`), []byte(`{"name": "Alice"}`))
|
f.Add([]byte(`[["==", ".name", "Alice"]]`), []byte(`{"name": "Alice"}`))
|
||||||
|
f.Add([]byte(`[["!=", ".name", "Alice"]]`), []byte(`{"name": "Alice"}`))
|
||||||
f.Add([]byte(`[[">", ".age", 30]]`), []byte(`{"age": 31}`))
|
f.Add([]byte(`[[">", ".age", 30]]`), []byte(`{"age": 31}`))
|
||||||
f.Add([]byte(`[["<=", ".height", 180]]`), []byte(`{"height": 170}`))
|
f.Add([]byte(`[["<=", ".height", 180]]`), []byte(`{"height": 170}`))
|
||||||
f.Add([]byte(`[["not", ["==", ".status", "inactive"]]]`), []byte(`{"status": "active"}`))
|
f.Add([]byte(`[["not", ["==", ".status", "inactive"]]]`), []byte(`{"status": "active"}`))
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
||||||
|
|
||||||
selpkg "github.com/ucan-wg/go-ucan/pkg/policy/selector"
|
selpkg "code.sonr.org/go/ucan/pkg/policy/selector"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
KindEqual = "==" // implemented by equality
|
KindEqual = "==" // implemented by equality
|
||||||
|
KindNotEqual = "!=" // implemented by equality
|
||||||
KindGreaterThan = ">" // implemented by equality
|
KindGreaterThan = ">" // implemented by equality
|
||||||
KindGreaterThanOrEqual = ">=" // implemented by equality
|
KindGreaterThanOrEqual = ">=" // implemented by equality
|
||||||
KindLessThan = "<" // implemented by equality
|
KindLessThan = "<" // implemented by equality
|
||||||
@@ -87,6 +88,13 @@ func Equal(selector string, value ipld.Node) Constructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NotEqual(selector string, value ipld.Node) Constructor {
|
||||||
|
return func() (Statement, error) {
|
||||||
|
sel, err := selpkg.Parse(selector)
|
||||||
|
return equality{kind: KindNotEqual, selector: sel, value: value}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func GreaterThan(selector string, value ipld.Node) Constructor {
|
func GreaterThan(selector string, value ipld.Node) Constructor {
|
||||||
return func() (Statement, error) {
|
return func() (Statement, error) {
|
||||||
sel, err := selpkg.Parse(selector)
|
sel, err := selpkg.Parse(selector)
|
||||||
@@ -125,7 +133,7 @@ func (n negation) Kind() string {
|
|||||||
|
|
||||||
func (n negation) String() string {
|
func (n negation) String() string {
|
||||||
child := n.statement.String()
|
child := n.statement.String()
|
||||||
return fmt.Sprintf(`["%s", "%s"]`, n.Kind(), strings.ReplaceAll(child, "\n", "\n "))
|
return fmt.Sprintf(`["%s", %s]`, n.Kind(), strings.ReplaceAll(child, "\n", "\n "))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Not(cstor Constructor) Constructor {
|
func Not(cstor Constructor) Constructor {
|
||||||
@@ -149,7 +157,7 @@ func (c connective) String() string {
|
|||||||
for i, statement := range c.statements {
|
for i, statement := range c.statements {
|
||||||
childs[i] = strings.ReplaceAll(statement.String(), "\n", "\n ")
|
childs[i] = strings.ReplaceAll(statement.String(), "\n", "\n ")
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("[\"%s\", [\n %s]]\n", c.kind, strings.Join(childs, ",\n "))
|
return fmt.Sprintf("[\"%s\", [\n %s\n]]", c.kind, strings.Join(childs, ",\n "))
|
||||||
}
|
}
|
||||||
|
|
||||||
func And(cstors ...Constructor) Constructor {
|
func And(cstors ...Constructor) Constructor {
|
||||||
@@ -208,7 +216,7 @@ func (n quantifier) Kind() string {
|
|||||||
|
|
||||||
func (n quantifier) String() string {
|
func (n quantifier) String() string {
|
||||||
child := n.statement.String()
|
child := n.statement.String()
|
||||||
return fmt.Sprintf("[\"%s\", \"%s\",\n %s]", n.Kind(), n.selector, strings.ReplaceAll(child, "\n", "\n "))
|
return fmt.Sprintf("[\"%s\", \"%s\",\n %s\n]", n.Kind(), n.selector, strings.ReplaceAll(child, "\n", "\n "))
|
||||||
}
|
}
|
||||||
|
|
||||||
func All(selector string, cstor Constructor) Constructor {
|
func All(selector string, cstor Constructor) Constructor {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy"
|
"code.sonr.org/go/ucan/pkg/policy"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
"code.sonr.org/go/ucan/pkg/policy/literal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExamplePolicy() {
|
func ExamplePolicy() {
|
||||||
@@ -28,11 +28,13 @@ func ExamplePolicy() {
|
|||||||
// [
|
// [
|
||||||
// ["==", ".status", "draft"],
|
// ["==", ".status", "draft"],
|
||||||
// ["all", ".reviewer",
|
// ["all", ".reviewer",
|
||||||
// ["like", ".email", "*@example.com"]],
|
// ["like", ".email", "*@example.com"]
|
||||||
|
// ],
|
||||||
// ["any", ".tags",
|
// ["any", ".tags",
|
||||||
// ["or", [
|
// ["or", [
|
||||||
// ["==", ".", "news"],
|
// ["==", ".", "news"],
|
||||||
// ["==", ".", "press"]]]
|
// ["==", ".", "press"]
|
||||||
|
// ]]
|
||||||
// ]
|
// ]
|
||||||
// ]
|
// ]
|
||||||
}
|
}
|
||||||
@@ -59,11 +61,13 @@ func ExamplePolicy_accumulate() {
|
|||||||
// [
|
// [
|
||||||
// ["==", ".status", "draft"],
|
// ["==", ".status", "draft"],
|
||||||
// ["all", ".reviewer",
|
// ["all", ".reviewer",
|
||||||
// ["like", ".email", "*@example.com"]],
|
// ["like", ".email", "*@example.com"]
|
||||||
|
// ],
|
||||||
// ["any", ".tags",
|
// ["any", ".tags",
|
||||||
// ["or", [
|
// ["or", [
|
||||||
// ["==", ".", "news"],
|
// ["==", ".", "news"],
|
||||||
// ["==", ".", "press"]]]
|
// ["==", ".", "press"]
|
||||||
|
// ]]
|
||||||
// ]
|
// ]
|
||||||
// ]
|
// ]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ package policytest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/args"
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy"
|
"code.sonr.org/go/ucan/pkg/args"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
"code.sonr.org/go/ucan/pkg/policy"
|
||||||
|
"code.sonr.org/go/ucan/pkg/policy/literal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EmptyPolicy provides a Policy with no statements.
|
// EmptyPolicy provides a Policy with no statements.
|
||||||
var EmptyPolicy = policy.Policy{}
|
var EmptyPolicy = policy.Policy{}
|
||||||
|
|
||||||
// ExampleValidationPolicy provides a instantiated SpecPolicy containing the
|
// SpecPolicy provides a valid Policy containing the statements that are included
|
||||||
// statements that are included in the second code block of the [Validation]
|
// in the second code block of the [Validation] section of the delegation specification.
|
||||||
// section of the delegation specification.
|
|
||||||
//
|
//
|
||||||
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
||||||
var SpecPolicy = policy.MustConstruct(
|
var SpecPolicy = policy.MustConstruct(
|
||||||
@@ -24,8 +24,8 @@ var SpecPolicy = policy.MustConstruct(
|
|||||||
// specification has been finished/merged.
|
// specification has been finished/merged.
|
||||||
|
|
||||||
// SpecValidArguments provides valid, instantiated Arguments containing
|
// SpecValidArguments provides valid, instantiated Arguments containing
|
||||||
// the key/value pairs that are included in portion of the the second code
|
// the key/value pairs that are included in portion of the second code block
|
||||||
// block of the [Validation] section of the delegation specification.
|
// of the [Validation] section of the delegation specification.
|
||||||
//
|
//
|
||||||
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
||||||
var SpecValidArguments = args.NewBuilder().
|
var SpecValidArguments = args.NewBuilder().
|
||||||
@@ -41,8 +41,8 @@ var SpecValidArguments = args.NewBuilder().
|
|||||||
var specValidArgumentsIPLD = mustIPLD(SpecValidArguments)
|
var specValidArgumentsIPLD = mustIPLD(SpecValidArguments)
|
||||||
|
|
||||||
// SpecInvalidArguments provides invalid, instantiated Arguments containing
|
// SpecInvalidArguments provides invalid, instantiated Arguments containing
|
||||||
// the key/value pairs that are included in portion of the the second code
|
// the key/value pairs that are included in portion of the second code block
|
||||||
// block of the [Validation] section of the delegation specification.
|
// of the [Validation] section of the delegation specification.
|
||||||
//
|
//
|
||||||
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
||||||
var SpecInvalidArguments = args.NewBuilder().
|
var SpecInvalidArguments = args.NewBuilder().
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/limits"
|
"code.sonr.org/go/ucan/pkg/policy/limits"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -68,7 +68,7 @@ func Parse(str string) (Selector, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newParseError("invalid index", str, col, tok)
|
return nil, newParseError("invalid index", str, col, tok)
|
||||||
}
|
}
|
||||||
if idx > limits.MaxInt53 || idx < limits.MinInt53 {
|
if int64(idx) > limits.MaxInt53 || int64(idx) < limits.MinInt53 {
|
||||||
return nil, newParseError(fmt.Sprintf("index %d exceeds safe integer bounds", idx), str, col, tok)
|
return nil, newParseError(fmt.Sprintf("index %d exceeds safe integer bounds", idx), str, col, tok)
|
||||||
}
|
}
|
||||||
sel = append(sel, segment{str: tok, optional: opt, index: idx})
|
sel = append(sel, segment{str: tok, optional: opt, index: idx})
|
||||||
@@ -173,37 +173,37 @@ func tokenize(str string) []string {
|
|||||||
return toks
|
return toks
|
||||||
}
|
}
|
||||||
|
|
||||||
type parseerr struct {
|
type parseErr struct {
|
||||||
msg string
|
msg string
|
||||||
src string
|
src string
|
||||||
col int
|
col int
|
||||||
tok string
|
tok string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p parseerr) Name() string {
|
func (p parseErr) Name() string {
|
||||||
return "ParseError"
|
return "ParseError"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p parseerr) Message() string {
|
func (p parseErr) Message() string {
|
||||||
return p.msg
|
return p.msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p parseerr) Column() int {
|
func (p parseErr) Column() int {
|
||||||
return p.col
|
return p.col
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p parseerr) Error() string {
|
func (p parseErr) Error() string {
|
||||||
return p.msg
|
return p.msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p parseerr) Source() string {
|
func (p parseErr) Source() string {
|
||||||
return p.src
|
return p.src
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p parseerr) Token() string {
|
func (p parseErr) Token() string {
|
||||||
return p.tok
|
return p.tok
|
||||||
}
|
}
|
||||||
|
|
||||||
func newParseError(message string, source string, column int, token string) error {
|
func newParseError(message string, source string, column int, token string) error {
|
||||||
return parseerr{message, source, column, token}
|
return parseErr{message, source, column, token}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/limits"
|
"code.sonr.org/go/ucan/pkg/policy/limits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestParse(t *testing.T) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type Selector []segment
|
|||||||
// Select perform the selection described by the selector on the input IPLD DAG.
|
// Select perform the selection described by the selector on the input IPLD DAG.
|
||||||
// Select can return:
|
// Select can return:
|
||||||
// - exactly one matched IPLD node
|
// - exactly one matched IPLD node
|
||||||
// - a resolutionerr error if not being able to resolve to a node
|
// - a resolutionErr error if not being able to resolve to a node
|
||||||
// - nil and no errors, if the selector couldn't match on an optional segment (with ?).
|
// - nil and no errors, if the selector couldn't match on an optional segment (with ?).
|
||||||
func (s Selector) Select(subject ipld.Node) (ipld.Node, error) {
|
func (s Selector) Select(subject ipld.Node) (ipld.Node, error) {
|
||||||
return resolve(s, subject, nil)
|
return resolve(s, subject, nil)
|
||||||
@@ -316,27 +316,27 @@ func kindString(n datamodel.Node) string {
|
|||||||
return n.Kind().String()
|
return n.Kind().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type resolutionerr struct {
|
type resolutionErr struct {
|
||||||
msg string
|
msg string
|
||||||
at []string
|
at []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r resolutionerr) Name() string {
|
func (r resolutionErr) Name() string {
|
||||||
return "ResolutionError"
|
return "ResolutionError"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r resolutionerr) Message() string {
|
func (r resolutionErr) Message() string {
|
||||||
return fmt.Sprintf("can not resolve path: .%s", strings.Join(r.at, "."))
|
return fmt.Sprintf("can not resolve path: .%s", strings.Join(r.at, "."))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r resolutionerr) At() []string {
|
func (r resolutionErr) At() []string {
|
||||||
return r.at
|
return r.at
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r resolutionerr) Error() string {
|
func (r resolutionErr) Error() string {
|
||||||
return r.Message()
|
return r.Message()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newResolutionError(message string, at []string) error {
|
func newResolutionError(message string, at []string) error {
|
||||||
return resolutionerr{message, at}
|
return resolutionErr{message, at}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ func TestSelect(t *testing.T) {
|
|||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Empty(t, res)
|
require.Empty(t, res)
|
||||||
|
|
||||||
require.ErrorAs(t, err, &resolutionerr{}, "error should be a resolution error")
|
require.ErrorAs(t, err, &resolutionErr{}, "error should be a resolution error")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("optional not exists", func(t *testing.T) {
|
t.Run("optional not exists", func(t *testing.T) {
|
||||||
@@ -351,7 +351,7 @@ func FuzzParseAndSelect(f *testing.F) {
|
|||||||
|
|
||||||
// look for panic()
|
// look for panic()
|
||||||
_, err = sel.Select(node)
|
_, err = sel.Select(node)
|
||||||
if err != nil && !errors.As(err, &resolutionerr{}) {
|
if err != nil && !errors.As(err, &resolutionErr{}) {
|
||||||
// not normal, we should only have resolution errors
|
// not normal, we should only have resolution errors
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
basicnode "github.com/ipld/go-ipld-prime/node/basic"
|
basicnode "github.com/ipld/go-ipld-prime/node/basic"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/selector"
|
"code.sonr.org/go/ucan/pkg/policy/selector"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestSupported Forms runs tests against the Selector according to the
|
// TestSupported Forms runs tests against the Selector according to the
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did"
|
"code.sonr.org/go/did-it"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/command"
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/meta"
|
"code.sonr.org/go/ucan/pkg/command"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy"
|
"code.sonr.org/go/ucan/pkg/meta"
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/nonce"
|
"code.sonr.org/go/ucan/pkg/policy"
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/parse"
|
"code.sonr.org/go/ucan/token/internal/nonce"
|
||||||
|
"code.sonr.org/go/ucan/token/internal/parse"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Token is an immutable type that holds the fields of a UCAN delegation.
|
// Token is an immutable type that holds the fields of a UCAN delegation.
|
||||||
@@ -83,7 +84,7 @@ func New(iss did.DID, aud did.DID, cmd command.Command, pol policy.Policy, sub d
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Root creates a validated UCAN delegation Token from the provided parameters and options.
|
// Root creates a validated UCAN delegation Token from the provided parameters and options.
|
||||||
// This is typically used to create and give a power to an agent.
|
// This is typically used to create and give power to an agent.
|
||||||
//
|
//
|
||||||
// You can read it as "(issuer) allows (audience) to perform (cmd+pol) on itself".
|
// You can read it as "(issuer) allows (audience) to perform (cmd+pol) on itself".
|
||||||
func Root(iss did.DID, aud did.DID, cmd command.Command, pol policy.Policy, opts ...Option) (*Token, error) {
|
func Root(iss did.DID, aud did.DID, cmd command.Command, pol policy.Policy, opts ...Option) (*Token, error) {
|
||||||
@@ -102,7 +103,7 @@ func Root(iss did.DID, aud did.DID, cmd command.Command, pol policy.Policy, opts
|
|||||||
//
|
//
|
||||||
// You can read it as "(issuer) allows (audience) to perform (cmd+pol) on anything".
|
// You can read it as "(issuer) allows (audience) to perform (cmd+pol) on anything".
|
||||||
func Powerline(iss did.DID, aud did.DID, cmd command.Command, pol policy.Policy, opts ...Option) (*Token, error) {
|
func Powerline(iss did.DID, aud did.DID, cmd command.Command, pol policy.Policy, opts ...Option) (*Token, error) {
|
||||||
return New(iss, aud, cmd, pol, did.Undef, opts...)
|
return New(iss, aud, cmd, pol, nil, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issuer returns the did.DID representing the Token's issuer.
|
// Issuer returns the did.DID representing the Token's issuer.
|
||||||
@@ -154,6 +155,16 @@ func (t *Token) Expiration() *time.Time {
|
|||||||
return t.expiration
|
return t.expiration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsRoot tells if the token is a root delegation.
|
||||||
|
func (t *Token) IsRoot() bool {
|
||||||
|
return t.issuer.Equal(t.subject)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPowerline tells if the token is a powerline delegation.
|
||||||
|
func (t *Token) IsPowerline() bool {
|
||||||
|
return t.subject == nil
|
||||||
|
}
|
||||||
|
|
||||||
// IsValidNow verifies that the token can be used at the current time, based on expiration or "not before" fields.
|
// IsValidNow verifies that the token can be used at the current time, based on expiration or "not before" fields.
|
||||||
// This does NOT do any other kind of verifications.
|
// This does NOT do any other kind of verifications.
|
||||||
func (t *Token) IsValidNow() bool {
|
func (t *Token) IsValidNow() bool {
|
||||||
@@ -172,25 +183,6 @@ func (t *Token) IsValidAt(ti time.Time) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Covers indicate if this token has the power to allow the given sub-delegation.
|
|
||||||
// This function only verifies the principals alignment
|
|
||||||
func (t *Token) Covers(subDelegation *Token) bool {
|
|
||||||
// The Subject of each delegation must equal the invocation's Subject (or Audience if defined). - 4f
|
|
||||||
if t.Subject() != sub {
|
|
||||||
return fmt.Errorf("%w: delegation %s, expected %s, got %s", ErrWrongSub, dlgCid, sub, dlg.Subject())
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Issuer of each delegation must be the Audience in the next one. - 4d
|
|
||||||
if t.Audience() != subDelegation.Issuer() {
|
|
||||||
return fmt.Errorf("%w: delegation %s, expected %s, got %s", ErrBrokenChain, dlgCid, iss, dlg.Audience())
|
|
||||||
}
|
|
||||||
|
|
||||||
// The command of each delegation must "allow" the one before it. - 4g
|
|
||||||
if !dlg.Command().Covers(cmd) {
|
|
||||||
return fmt.Errorf("%w: delegation %s, %s doesn't cover %s", ErrCommandNotCovered, dlgCid, dlg.Command(), cmd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Token) String() string {
|
func (t *Token) String() string {
|
||||||
var res strings.Builder
|
var res strings.Builder
|
||||||
|
|
||||||
@@ -198,7 +190,7 @@ func (t *Token) String() string {
|
|||||||
switch {
|
switch {
|
||||||
case t.issuer == t.subject:
|
case t.issuer == t.subject:
|
||||||
kind = " (root delegation)"
|
kind = " (root delegation)"
|
||||||
case t.subject == did.Undef:
|
case t.subject == nil:
|
||||||
kind = " (powerline delegation)"
|
kind = " (powerline delegation)"
|
||||||
default:
|
default:
|
||||||
kind = " (normal delegation)"
|
kind = " (normal delegation)"
|
||||||
@@ -221,7 +213,7 @@ func (t *Token) validate() error {
|
|||||||
var errs error
|
var errs error
|
||||||
|
|
||||||
requiredDID := func(id did.DID, fieldname string) {
|
requiredDID := func(id did.DID, fieldname string) {
|
||||||
if !id.Defined() {
|
if id == nil {
|
||||||
errs = errors.Join(errs, fmt.Errorf(`a valid did is required for %s: %s`, fieldname, id.String()))
|
errs = errors.Join(errs, fmt.Errorf(`a valid did is required for %s: %s`, fieldname, id.String()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +1,43 @@
|
|||||||
package delegation_test
|
package delegation_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "embed"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it/didtest"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gotest.tools/v3/golden"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did/didtest"
|
"code.sonr.org/go/ucan/pkg/command"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/command"
|
"code.sonr.org/go/ucan/pkg/policy"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed testdata/new.dagjson
|
||||||
|
var newDagJson []byte
|
||||||
|
|
||||||
|
//go:embed testdata/powerline.dagjson
|
||||||
|
var powerlineDagJson []byte
|
||||||
|
|
||||||
|
//go:embed testdata/root.dagjson
|
||||||
|
var rootDagJson []byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
nonce = "6roDhGi0kiNriQAz7J3d+bOeoI/tj8ENikmQNbtjnD0"
|
nonce = "6roDhGi0kiNriQAz7J3d+bOeoI/tj8ENikmQNbtjnD0"
|
||||||
|
|
||||||
subJectCmd = "/foo/bar"
|
subJectCmd = "/foo/bar"
|
||||||
subjectPol = `
|
subjectPol = `
|
||||||
[
|
[
|
||||||
[
|
["==", ".status", "draft"],
|
||||||
"==",
|
["all", ".reviewer",
|
||||||
".status",
|
["like", ".email", "*@example.com"]
|
||||||
"draft"
|
|
||||||
],
|
],
|
||||||
[
|
["any", ".tags",
|
||||||
"all",
|
["or", [
|
||||||
".reviewer",
|
["==", ".", "news"],
|
||||||
[
|
["==", ".", "press"]
|
||||||
"like",
|
]]
|
||||||
".email",
|
|
||||||
"*@example.com"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"any",
|
|
||||||
".tags",
|
|
||||||
[
|
|
||||||
"or",
|
|
||||||
[
|
|
||||||
[
|
|
||||||
"==",
|
|
||||||
".",
|
|
||||||
"news"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"==",
|
|
||||||
".",
|
|
||||||
"press"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
`
|
`
|
||||||
@@ -80,15 +66,16 @@ func TestConstructors(t *testing.T) {
|
|||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.False(t, tkn.IsRoot())
|
||||||
|
require.False(t, tkn.IsPowerline())
|
||||||
|
|
||||||
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
golden.Assert(t, string(data), "new.dagjson")
|
require.Equal(t, newDagJson, data)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Root", func(t *testing.T) {
|
t.Run("Root", func(t *testing.T) {
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
tkn, err := delegation.Root(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol,
|
tkn, err := delegation.Root(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol,
|
||||||
delegation.WithNonce([]byte(nonce)),
|
delegation.WithNonce([]byte(nonce)),
|
||||||
delegation.WithExpiration(exp),
|
delegation.WithExpiration(exp),
|
||||||
@@ -97,15 +84,16 @@ func TestConstructors(t *testing.T) {
|
|||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.True(t, tkn.IsRoot())
|
||||||
|
require.False(t, tkn.IsPowerline())
|
||||||
|
|
||||||
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
golden.Assert(t, string(data), "root.dagjson")
|
require.Equal(t, rootDagJson, data)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Powerline", func(t *testing.T) {
|
t.Run("Powerline", func(t *testing.T) {
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
tkn, err := delegation.Powerline(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol,
|
tkn, err := delegation.Powerline(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol,
|
||||||
delegation.WithNonce([]byte(nonce)),
|
delegation.WithNonce([]byte(nonce)),
|
||||||
delegation.WithExpiration(exp),
|
delegation.WithExpiration(exp),
|
||||||
@@ -114,10 +102,13 @@ func TestConstructors(t *testing.T) {
|
|||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.False(t, tkn.IsRoot())
|
||||||
|
require.True(t, tkn.IsPowerline())
|
||||||
|
|
||||||
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
golden.Assert(t, string(data), "powerline.dagjson")
|
require.Equal(t, powerlineDagJson, data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -9,16 +9,17 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it"
|
||||||
|
didkeyctl "code.sonr.org/go/did-it/controller/did-key"
|
||||||
|
"code.sonr.org/go/did-it/crypto"
|
||||||
|
"code.sonr.org/go/did-it/didtest"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did"
|
"code.sonr.org/go/ucan/pkg/command"
|
||||||
"github.com/ucan-wg/go-ucan/did/didtest"
|
"code.sonr.org/go/ucan/pkg/policy"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/command"
|
"code.sonr.org/go/ucan/pkg/policy/policytest"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/policytest"
|
"code.sonr.org/go/ucan/token/delegation/delegationtest"
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation/delegationtest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -30,7 +31,7 @@ const (
|
|||||||
var constantNonce = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b}
|
var constantNonce = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b}
|
||||||
|
|
||||||
type newDelegationParams struct {
|
type newDelegationParams struct {
|
||||||
privKey crypto.PrivKey // iss
|
privKey crypto.PrivateKeySigningBytes // iss
|
||||||
aud did.DID
|
aud did.DID
|
||||||
cmd command.Command
|
cmd command.Command
|
||||||
pol policy.Policy
|
pol policy.Policy
|
||||||
@@ -157,10 +158,7 @@ func (g *generator) chainPersonas(personas []didtest.Persona, acc acc, vari vari
|
|||||||
func (g *generator) createDelegation(params newDelegationParams, name string, vari variant) (cid.Cid, error) {
|
func (g *generator) createDelegation(params newDelegationParams, name string, vari variant) (cid.Cid, error) {
|
||||||
vari.variant(¶ms)
|
vari.variant(¶ms)
|
||||||
|
|
||||||
issDID, err := did.FromPrivKey(params.privKey)
|
issDID := didkeyctl.FromPrivateKey(params.privKey)
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
tkn, err := delegation.New(issDID, params.aud, params.cmd, params.pol, params.sub, params.opts...)
|
tkn, err := delegation.New(issDID, params.aud, params.cmd, params.pol, params.sub, params.opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -217,7 +215,7 @@ func (g *generator) writeGoFile() error {
|
|||||||
Println("import (")
|
Println("import (")
|
||||||
Println("\t\"github.com/ipfs/go-cid\"")
|
Println("\t\"github.com/ipfs/go-cid\"")
|
||||||
Println()
|
Println()
|
||||||
Println("\t\"github.com/ucan-wg/go-ucan/token/delegation\"")
|
Println("\t\"code.sonr.org/go/ucan/token/delegation\"")
|
||||||
Println(")")
|
Println(")")
|
||||||
|
|
||||||
refs := make(map[cid.Cid]string, len(g.dlgs))
|
refs := make(map[cid.Cid]string, len(g.dlgs))
|
||||||
@@ -242,7 +240,7 @@ func (g *generator) writeGoFile() error {
|
|||||||
Println("}")
|
Println("}")
|
||||||
|
|
||||||
Println()
|
Println()
|
||||||
Println("var AllBundles = []*delegation.Bundle{")
|
Println("var AllBundles = []delegation.Bundle{")
|
||||||
for _, d := range g.dlgs {
|
for _, d := range g.dlgs {
|
||||||
Printf("\t%sBundle,\n", d.name)
|
Printf("\t%sBundle,\n", d.name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ucan-wg/go-ucan/did/didtest"
|
"code.sonr.org/go/did-it/didtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
_ "code.sonr.org/go/did-it/verifiers/did-key"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/command"
|
"code.sonr.org/go/ucan/pkg/command"
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -38,7 +39,7 @@ var fs embed.FS
|
|||||||
var _ delegation.Loader = (*DelegationLoader)(nil)
|
var _ delegation.Loader = (*DelegationLoader)(nil)
|
||||||
|
|
||||||
type DelegationLoader struct {
|
type DelegationLoader struct {
|
||||||
bundles map[cid.Cid]*delegation.Bundle
|
bundles map[cid.Cid]delegation.Bundle
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -75,7 +76,7 @@ func loadDelegations() (*DelegationLoader, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bundles := make(map[cid.Cid]*delegation.Bundle, len(dirEntries))
|
bundles := make(map[cid.Cid]delegation.Bundle, len(dirEntries))
|
||||||
|
|
||||||
for _, dirEntry := range dirEntries {
|
for _, dirEntry := range dirEntries {
|
||||||
data, err := fs.ReadFile(filepath.Join(TokenDir, dirEntry.Name()))
|
data, err := fs.ReadFile(filepath.Join(TokenDir, dirEntry.Name()))
|
||||||
@@ -88,7 +89,7 @@ func loadDelegations() (*DelegationLoader, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bundles[id] = &delegation.Bundle{Cid: id, Decoded: tkn, Sealed: data}
|
bundles[id] = delegation.Bundle{Cid: id, Decoded: tkn, Sealed: data}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &DelegationLoader{
|
return &DelegationLoader{
|
||||||
@@ -106,7 +107,7 @@ func CidToName(id cid.Cid) string {
|
|||||||
return cidToName[id]
|
return cidToName[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustGetBundle(id cid.Cid) *delegation.Bundle {
|
func mustGetBundle(id cid.Cid) delegation.Bundle {
|
||||||
bundle, ok := GetDelegationLoader().bundles[id]
|
bundle, ok := GetDelegationLoader().bundles[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(delegation.ErrDelegationNotFound)
|
panic(delegation.ErrDelegationNotFound)
|
||||||
|
|||||||
@@ -5,165 +5,165 @@ package delegationtest
|
|||||||
import (
|
import (
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenAliceBobCID = cid.MustParse("bafyreicidrwvmac5lvjypucgityrtjsknojraio7ujjli4r5eyby66wjzm")
|
TokenAliceBobCID = cid.MustParse("bafyreifa35rjstdm37cjudzs72ab22rnh5blny725khtapox63fnsj6pbe")
|
||||||
TokenAliceBobSealed = mustGetBundle(TokenAliceBobCID).Sealed
|
TokenAliceBobSealed = mustGetBundle(TokenAliceBobCID).Sealed
|
||||||
TokenAliceBobBundle = mustGetBundle(TokenAliceBobCID)
|
TokenAliceBobBundle = mustGetBundle(TokenAliceBobCID)
|
||||||
TokenAliceBob = mustGetBundle(TokenAliceBobCID).Decoded
|
TokenAliceBob = mustGetBundle(TokenAliceBobCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenBobCarolCID = cid.MustParse("bafyreihxv2uhq43oxllzs2xfvxst7wtvvvl7pohb2chcz6hjvfv2ntea5u")
|
TokenBobCarolCID = cid.MustParse("bafyreiaysaafvfplhjsjywaqfletlr2sziui3sekkczwp2srszdoezwc7u")
|
||||||
TokenBobCarolSealed = mustGetBundle(TokenBobCarolCID).Sealed
|
TokenBobCarolSealed = mustGetBundle(TokenBobCarolCID).Sealed
|
||||||
TokenBobCarolBundle = mustGetBundle(TokenBobCarolCID)
|
TokenBobCarolBundle = mustGetBundle(TokenBobCarolCID)
|
||||||
TokenBobCarol = mustGetBundle(TokenBobCarolCID).Decoded
|
TokenBobCarol = mustGetBundle(TokenBobCarolCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenCarolDanCID = cid.MustParse("bafyreihclsgiroazq3heqdswvj2cafwqbpboicq7immo65scl7ahktpsdq")
|
TokenCarolDanCID = cid.MustParse("bafyreibwpzxcvrere7g5riv3dhza4xibrvulxcvj2nwxu6ozp572o2sbfa")
|
||||||
TokenCarolDanSealed = mustGetBundle(TokenCarolDanCID).Sealed
|
TokenCarolDanSealed = mustGetBundle(TokenCarolDanCID).Sealed
|
||||||
TokenCarolDanBundle = mustGetBundle(TokenCarolDanCID)
|
TokenCarolDanBundle = mustGetBundle(TokenCarolDanCID)
|
||||||
TokenCarolDan = mustGetBundle(TokenCarolDanCID).Decoded
|
TokenCarolDan = mustGetBundle(TokenCarolDanCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenDanErinCID = cid.MustParse("bafyreicja6ihewy64p3ake56xukotafjlkh4uqep2qhj52en46zzfwby3e")
|
TokenDanErinCID = cid.MustParse("bafyreichxodkcokcbvomxhmlf3g3j3zokruxvca63itynf7ib3hsmi4hla")
|
||||||
TokenDanErinSealed = mustGetBundle(TokenDanErinCID).Sealed
|
TokenDanErinSealed = mustGetBundle(TokenDanErinCID).Sealed
|
||||||
TokenDanErinBundle = mustGetBundle(TokenDanErinCID)
|
TokenDanErinBundle = mustGetBundle(TokenDanErinCID)
|
||||||
TokenDanErin = mustGetBundle(TokenDanErinCID).Decoded
|
TokenDanErin = mustGetBundle(TokenDanErinCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenErinFrankCID = cid.MustParse("bafyreicjlx3lobxm6hl5s4htd4ydwkkqeiou6rft4rnvulfdyoew565vka")
|
TokenErinFrankCID = cid.MustParse("bafyreigg434khwxqyfasnk63pi542uwtbrlpfd5sgjfrddqqcba3tardlu")
|
||||||
TokenErinFrankSealed = mustGetBundle(TokenErinFrankCID).Sealed
|
TokenErinFrankSealed = mustGetBundle(TokenErinFrankCID).Sealed
|
||||||
TokenErinFrankBundle = mustGetBundle(TokenErinFrankCID)
|
TokenErinFrankBundle = mustGetBundle(TokenErinFrankCID)
|
||||||
TokenErinFrank = mustGetBundle(TokenErinFrankCID).Decoded
|
TokenErinFrank = mustGetBundle(TokenErinFrankCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenCarolDan_InvalidExpandedCommandCID = cid.MustParse("bafyreid3m3pk53gqgp5rlzqhvpedbwsqbidqlp4yz64vknwbzj7bxrmsr4")
|
TokenCarolDan_InvalidExpandedCommandCID = cid.MustParse("bafyreifxdve23izhlg7fhzqh32i6wxtw33rqidm3cb72pghxlovnensjwe")
|
||||||
TokenCarolDan_InvalidExpandedCommandSealed = mustGetBundle(TokenCarolDan_InvalidExpandedCommandCID).Sealed
|
TokenCarolDan_InvalidExpandedCommandSealed = mustGetBundle(TokenCarolDan_InvalidExpandedCommandCID).Sealed
|
||||||
TokenCarolDan_InvalidExpandedCommandBundle = mustGetBundle(TokenCarolDan_InvalidExpandedCommandCID)
|
TokenCarolDan_InvalidExpandedCommandBundle = mustGetBundle(TokenCarolDan_InvalidExpandedCommandCID)
|
||||||
TokenCarolDan_InvalidExpandedCommand = mustGetBundle(TokenCarolDan_InvalidExpandedCommandCID).Decoded
|
TokenCarolDan_InvalidExpandedCommand = mustGetBundle(TokenCarolDan_InvalidExpandedCommandCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenDanErin_InvalidExpandedCommandCID = cid.MustParse("bafyreifn4sy5onwajx3kqvot5mib6m6xarzrqjozqbzgmzpmc5ox3g2uzm")
|
TokenDanErin_InvalidExpandedCommandCID = cid.MustParse("bafyreieblevkqh2xnbr4x5mosvwv7rboat7ip6ucqvefb2pomrb4qjg4wu")
|
||||||
TokenDanErin_InvalidExpandedCommandSealed = mustGetBundle(TokenDanErin_InvalidExpandedCommandCID).Sealed
|
TokenDanErin_InvalidExpandedCommandSealed = mustGetBundle(TokenDanErin_InvalidExpandedCommandCID).Sealed
|
||||||
TokenDanErin_InvalidExpandedCommandBundle = mustGetBundle(TokenDanErin_InvalidExpandedCommandCID)
|
TokenDanErin_InvalidExpandedCommandBundle = mustGetBundle(TokenDanErin_InvalidExpandedCommandCID)
|
||||||
TokenDanErin_InvalidExpandedCommand = mustGetBundle(TokenDanErin_InvalidExpandedCommandCID).Decoded
|
TokenDanErin_InvalidExpandedCommand = mustGetBundle(TokenDanErin_InvalidExpandedCommandCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenErinFrank_InvalidExpandedCommandCID = cid.MustParse("bafyreidmpgd36jznmq42bs34o4qi3fcbrsh4idkg6ejahudejzwb76fwxe")
|
TokenErinFrank_InvalidExpandedCommandCID = cid.MustParse("bafyreia2ckukamhpeqpcdhevr75ym66vqem432dx4dwbdrdkh63pke3r3i")
|
||||||
TokenErinFrank_InvalidExpandedCommandSealed = mustGetBundle(TokenErinFrank_InvalidExpandedCommandCID).Sealed
|
TokenErinFrank_InvalidExpandedCommandSealed = mustGetBundle(TokenErinFrank_InvalidExpandedCommandCID).Sealed
|
||||||
TokenErinFrank_InvalidExpandedCommandBundle = mustGetBundle(TokenErinFrank_InvalidExpandedCommandCID)
|
TokenErinFrank_InvalidExpandedCommandBundle = mustGetBundle(TokenErinFrank_InvalidExpandedCommandCID)
|
||||||
TokenErinFrank_InvalidExpandedCommand = mustGetBundle(TokenErinFrank_InvalidExpandedCommandCID).Decoded
|
TokenErinFrank_InvalidExpandedCommand = mustGetBundle(TokenErinFrank_InvalidExpandedCommandCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenCarolDan_ValidAttenuatedCommandCID = cid.MustParse("bafyreiekhtm237vyapk3c6voeb5lnz54crebqdqi3x4wn4u4cbrrhzsqfe")
|
TokenCarolDan_ValidAttenuatedCommandCID = cid.MustParse("bafyreibftsq3mhjd5itg6jbos4doccwspvmnilpuduniv2el7mnl45z33y")
|
||||||
TokenCarolDan_ValidAttenuatedCommandSealed = mustGetBundle(TokenCarolDan_ValidAttenuatedCommandCID).Sealed
|
TokenCarolDan_ValidAttenuatedCommandSealed = mustGetBundle(TokenCarolDan_ValidAttenuatedCommandCID).Sealed
|
||||||
TokenCarolDan_ValidAttenuatedCommandBundle = mustGetBundle(TokenCarolDan_ValidAttenuatedCommandCID)
|
TokenCarolDan_ValidAttenuatedCommandBundle = mustGetBundle(TokenCarolDan_ValidAttenuatedCommandCID)
|
||||||
TokenCarolDan_ValidAttenuatedCommand = mustGetBundle(TokenCarolDan_ValidAttenuatedCommandCID).Decoded
|
TokenCarolDan_ValidAttenuatedCommand = mustGetBundle(TokenCarolDan_ValidAttenuatedCommandCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenDanErin_ValidAttenuatedCommandCID = cid.MustParse("bafyreicrvzqferyy7rgo75l5rn6r2nl7zyeexxjmu3dm4ff7rn2coblj4y")
|
TokenDanErin_ValidAttenuatedCommandCID = cid.MustParse("bafyreig5gsifqn3afnyaoqtjhnud2w7tnrda57eiel3d45vbp47hjyayey")
|
||||||
TokenDanErin_ValidAttenuatedCommandSealed = mustGetBundle(TokenDanErin_ValidAttenuatedCommandCID).Sealed
|
TokenDanErin_ValidAttenuatedCommandSealed = mustGetBundle(TokenDanErin_ValidAttenuatedCommandCID).Sealed
|
||||||
TokenDanErin_ValidAttenuatedCommandBundle = mustGetBundle(TokenDanErin_ValidAttenuatedCommandCID)
|
TokenDanErin_ValidAttenuatedCommandBundle = mustGetBundle(TokenDanErin_ValidAttenuatedCommandCID)
|
||||||
TokenDanErin_ValidAttenuatedCommand = mustGetBundle(TokenDanErin_ValidAttenuatedCommandCID).Decoded
|
TokenDanErin_ValidAttenuatedCommand = mustGetBundle(TokenDanErin_ValidAttenuatedCommandCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenErinFrank_ValidAttenuatedCommandCID = cid.MustParse("bafyreie6fhspk53kplcc2phla3e7z7fzldlbmmpuwk6nbow5q6s2zjmw2q")
|
TokenErinFrank_ValidAttenuatedCommandCID = cid.MustParse("bafyreiex2qyrw3xmye4fk5wdf6ukea3ojbokq77k6y566hupj6cicszi3e")
|
||||||
TokenErinFrank_ValidAttenuatedCommandSealed = mustGetBundle(TokenErinFrank_ValidAttenuatedCommandCID).Sealed
|
TokenErinFrank_ValidAttenuatedCommandSealed = mustGetBundle(TokenErinFrank_ValidAttenuatedCommandCID).Sealed
|
||||||
TokenErinFrank_ValidAttenuatedCommandBundle = mustGetBundle(TokenErinFrank_ValidAttenuatedCommandCID)
|
TokenErinFrank_ValidAttenuatedCommandBundle = mustGetBundle(TokenErinFrank_ValidAttenuatedCommandCID)
|
||||||
TokenErinFrank_ValidAttenuatedCommand = mustGetBundle(TokenErinFrank_ValidAttenuatedCommandCID).Decoded
|
TokenErinFrank_ValidAttenuatedCommand = mustGetBundle(TokenErinFrank_ValidAttenuatedCommandCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenCarolDan_InvalidSubjectCID = cid.MustParse("bafyreifgksz6756if42tnc6rqsnbaa2u3fdrveo7ek44lnj2d64d5sw26u")
|
TokenCarolDan_InvalidSubjectCID = cid.MustParse("bafyreie7snyknubaeh4ruig7wxvos54b7skmwsnegf6k23bsffs5btbiiq")
|
||||||
TokenCarolDan_InvalidSubjectSealed = mustGetBundle(TokenCarolDan_InvalidSubjectCID).Sealed
|
TokenCarolDan_InvalidSubjectSealed = mustGetBundle(TokenCarolDan_InvalidSubjectCID).Sealed
|
||||||
TokenCarolDan_InvalidSubjectBundle = mustGetBundle(TokenCarolDan_InvalidSubjectCID)
|
TokenCarolDan_InvalidSubjectBundle = mustGetBundle(TokenCarolDan_InvalidSubjectCID)
|
||||||
TokenCarolDan_InvalidSubject = mustGetBundle(TokenCarolDan_InvalidSubjectCID).Decoded
|
TokenCarolDan_InvalidSubject = mustGetBundle(TokenCarolDan_InvalidSubjectCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenDanErin_InvalidSubjectCID = cid.MustParse("bafyreibdwew5nypsxrm4fq73wu6hw3lgwwiolj3bi33xdrbgcf3ogm6fty")
|
TokenDanErin_InvalidSubjectCID = cid.MustParse("bafyreicrfmlw4nqqk5t7j6r7ct3c7jlxeasyetb6fq3556vmtihcnbi54i")
|
||||||
TokenDanErin_InvalidSubjectSealed = mustGetBundle(TokenDanErin_InvalidSubjectCID).Sealed
|
TokenDanErin_InvalidSubjectSealed = mustGetBundle(TokenDanErin_InvalidSubjectCID).Sealed
|
||||||
TokenDanErin_InvalidSubjectBundle = mustGetBundle(TokenDanErin_InvalidSubjectCID)
|
TokenDanErin_InvalidSubjectBundle = mustGetBundle(TokenDanErin_InvalidSubjectCID)
|
||||||
TokenDanErin_InvalidSubject = mustGetBundle(TokenDanErin_InvalidSubjectCID).Decoded
|
TokenDanErin_InvalidSubject = mustGetBundle(TokenDanErin_InvalidSubjectCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenErinFrank_InvalidSubjectCID = cid.MustParse("bafyreicr364mj3n7x4iyhcksxypelktcqkkw3ptg7ggxtqegw3p3mr6zc4")
|
TokenErinFrank_InvalidSubjectCID = cid.MustParse("bafyreietx2sjsm72sbgjnosdnejwlqc5dadlolh2bjl6ifxdllslup7ecm")
|
||||||
TokenErinFrank_InvalidSubjectSealed = mustGetBundle(TokenErinFrank_InvalidSubjectCID).Sealed
|
TokenErinFrank_InvalidSubjectSealed = mustGetBundle(TokenErinFrank_InvalidSubjectCID).Sealed
|
||||||
TokenErinFrank_InvalidSubjectBundle = mustGetBundle(TokenErinFrank_InvalidSubjectCID)
|
TokenErinFrank_InvalidSubjectBundle = mustGetBundle(TokenErinFrank_InvalidSubjectCID)
|
||||||
TokenErinFrank_InvalidSubject = mustGetBundle(TokenErinFrank_InvalidSubjectCID).Decoded
|
TokenErinFrank_InvalidSubject = mustGetBundle(TokenErinFrank_InvalidSubjectCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenCarolDan_InvalidExpiredCID = cid.MustParse("bafyreifyzm5jkx2sfu5awyndg3dn5zlg7sq5hssgfatafk62kiiilapnqe")
|
TokenCarolDan_InvalidExpiredCID = cid.MustParse("bafyreifhdiem6r5fh3wwaa6uszqe5uashfwaastqjyvzssbiju4mravx3y")
|
||||||
TokenCarolDan_InvalidExpiredSealed = mustGetBundle(TokenCarolDan_InvalidExpiredCID).Sealed
|
TokenCarolDan_InvalidExpiredSealed = mustGetBundle(TokenCarolDan_InvalidExpiredCID).Sealed
|
||||||
TokenCarolDan_InvalidExpiredBundle = mustGetBundle(TokenCarolDan_InvalidExpiredCID)
|
TokenCarolDan_InvalidExpiredBundle = mustGetBundle(TokenCarolDan_InvalidExpiredCID)
|
||||||
TokenCarolDan_InvalidExpired = mustGetBundle(TokenCarolDan_InvalidExpiredCID).Decoded
|
TokenCarolDan_InvalidExpired = mustGetBundle(TokenCarolDan_InvalidExpiredCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenDanErin_InvalidExpiredCID = cid.MustParse("bafyreihhnisabmkofuk3qaw37leijxqjaz5or6v2cufjxwzdkvuvv2dzbq")
|
TokenDanErin_InvalidExpiredCID = cid.MustParse("bafyreiff7fqutstzz2ep5gzs2mqnt4rka7ezscrzpijyc4jjeopqm7oxxq")
|
||||||
TokenDanErin_InvalidExpiredSealed = mustGetBundle(TokenDanErin_InvalidExpiredCID).Sealed
|
TokenDanErin_InvalidExpiredSealed = mustGetBundle(TokenDanErin_InvalidExpiredCID).Sealed
|
||||||
TokenDanErin_InvalidExpiredBundle = mustGetBundle(TokenDanErin_InvalidExpiredCID)
|
TokenDanErin_InvalidExpiredBundle = mustGetBundle(TokenDanErin_InvalidExpiredCID)
|
||||||
TokenDanErin_InvalidExpired = mustGetBundle(TokenDanErin_InvalidExpiredCID).Decoded
|
TokenDanErin_InvalidExpired = mustGetBundle(TokenDanErin_InvalidExpiredCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenErinFrank_InvalidExpiredCID = cid.MustParse("bafyreigeokaziviwm5kzmkpwesj3gta5k7zrd62x4a746fnrnkhvatwbna")
|
TokenErinFrank_InvalidExpiredCID = cid.MustParse("bafyreigxfwcynzsy4v4po36s3mz5nf6mg4kpptw6rpld3sc3c3mthq4noa")
|
||||||
TokenErinFrank_InvalidExpiredSealed = mustGetBundle(TokenErinFrank_InvalidExpiredCID).Sealed
|
TokenErinFrank_InvalidExpiredSealed = mustGetBundle(TokenErinFrank_InvalidExpiredCID).Sealed
|
||||||
TokenErinFrank_InvalidExpiredBundle = mustGetBundle(TokenErinFrank_InvalidExpiredCID)
|
TokenErinFrank_InvalidExpiredBundle = mustGetBundle(TokenErinFrank_InvalidExpiredCID)
|
||||||
TokenErinFrank_InvalidExpired = mustGetBundle(TokenErinFrank_InvalidExpiredCID).Decoded
|
TokenErinFrank_InvalidExpired = mustGetBundle(TokenErinFrank_InvalidExpiredCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenCarolDan_InvalidInactiveCID = cid.MustParse("bafyreicea5y2nvlitvxijkupeavtg23i7ktjk3uejnaquguurzptiabk4u")
|
TokenCarolDan_InvalidInactiveCID = cid.MustParse("bafyreifw4j2mxg4bovuhihvnhqgln7m57lvajt6fza4x4jc7sncyh66wxm")
|
||||||
TokenCarolDan_InvalidInactiveSealed = mustGetBundle(TokenCarolDan_InvalidInactiveCID).Sealed
|
TokenCarolDan_InvalidInactiveSealed = mustGetBundle(TokenCarolDan_InvalidInactiveCID).Sealed
|
||||||
TokenCarolDan_InvalidInactiveBundle = mustGetBundle(TokenCarolDan_InvalidInactiveCID)
|
TokenCarolDan_InvalidInactiveBundle = mustGetBundle(TokenCarolDan_InvalidInactiveCID)
|
||||||
TokenCarolDan_InvalidInactive = mustGetBundle(TokenCarolDan_InvalidInactiveCID).Decoded
|
TokenCarolDan_InvalidInactive = mustGetBundle(TokenCarolDan_InvalidInactiveCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenDanErin_InvalidInactiveCID = cid.MustParse("bafyreifsgqzkmxj2vexuts3z766mwcjreiisjg2jykyzf7tbj5sclutpvq")
|
TokenDanErin_InvalidInactiveCID = cid.MustParse("bafyreigrrfefw4wvjitiheonigeldnem2loo4yp5cghdskteunuxyozkiq")
|
||||||
TokenDanErin_InvalidInactiveSealed = mustGetBundle(TokenDanErin_InvalidInactiveCID).Sealed
|
TokenDanErin_InvalidInactiveSealed = mustGetBundle(TokenDanErin_InvalidInactiveCID).Sealed
|
||||||
TokenDanErin_InvalidInactiveBundle = mustGetBundle(TokenDanErin_InvalidInactiveCID)
|
TokenDanErin_InvalidInactiveBundle = mustGetBundle(TokenDanErin_InvalidInactiveCID)
|
||||||
TokenDanErin_InvalidInactive = mustGetBundle(TokenDanErin_InvalidInactiveCID).Decoded
|
TokenDanErin_InvalidInactive = mustGetBundle(TokenDanErin_InvalidInactiveCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenErinFrank_InvalidInactiveCID = cid.MustParse("bafyreifbfegon24c6dndiqyktahzs65vhyasrygbw7nhsvojn6distsdre")
|
TokenErinFrank_InvalidInactiveCID = cid.MustParse("bafyreicdlvnc7iinl2eay3xc3yvtmwezifvfxywjud3defssstusngt6du")
|
||||||
TokenErinFrank_InvalidInactiveSealed = mustGetBundle(TokenErinFrank_InvalidInactiveCID).Sealed
|
TokenErinFrank_InvalidInactiveSealed = mustGetBundle(TokenErinFrank_InvalidInactiveCID).Sealed
|
||||||
TokenErinFrank_InvalidInactiveBundle = mustGetBundle(TokenErinFrank_InvalidInactiveCID)
|
TokenErinFrank_InvalidInactiveBundle = mustGetBundle(TokenErinFrank_InvalidInactiveCID)
|
||||||
TokenErinFrank_InvalidInactive = mustGetBundle(TokenErinFrank_InvalidInactiveCID).Decoded
|
TokenErinFrank_InvalidInactive = mustGetBundle(TokenErinFrank_InvalidInactiveCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenCarolDan_ValidExamplePolicyCID = cid.MustParse("bafyreibtfrp2njnkjrcuhxd4ebaecmpcql5knek2h2j2fjzu2sij2tv6ei")
|
TokenCarolDan_ValidExamplePolicyCID = cid.MustParse("bafyreidvi5y42befcnb2qud23yt5memf4itn2v6xmw7gvdpihbnanvgqly")
|
||||||
TokenCarolDan_ValidExamplePolicySealed = mustGetBundle(TokenCarolDan_ValidExamplePolicyCID).Sealed
|
TokenCarolDan_ValidExamplePolicySealed = mustGetBundle(TokenCarolDan_ValidExamplePolicyCID).Sealed
|
||||||
TokenCarolDan_ValidExamplePolicyBundle = mustGetBundle(TokenCarolDan_ValidExamplePolicyCID)
|
TokenCarolDan_ValidExamplePolicyBundle = mustGetBundle(TokenCarolDan_ValidExamplePolicyCID)
|
||||||
TokenCarolDan_ValidExamplePolicy = mustGetBundle(TokenCarolDan_ValidExamplePolicyCID).Decoded
|
TokenCarolDan_ValidExamplePolicy = mustGetBundle(TokenCarolDan_ValidExamplePolicyCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenDanErin_ValidExamplePolicyCID = cid.MustParse("bafyreidxfwbkzujpu7ivulkc7b6ff4cpbzrkeklmxqvyhhmkmym5b45e2e")
|
TokenDanErin_ValidExamplePolicyCID = cid.MustParse("bafyreid3mr53fjsntyyfbbzjx2n32d7atj3v4ztfufdkamrodm6kcjww64")
|
||||||
TokenDanErin_ValidExamplePolicySealed = mustGetBundle(TokenDanErin_ValidExamplePolicyCID).Sealed
|
TokenDanErin_ValidExamplePolicySealed = mustGetBundle(TokenDanErin_ValidExamplePolicyCID).Sealed
|
||||||
TokenDanErin_ValidExamplePolicyBundle = mustGetBundle(TokenDanErin_ValidExamplePolicyCID)
|
TokenDanErin_ValidExamplePolicyBundle = mustGetBundle(TokenDanErin_ValidExamplePolicyCID)
|
||||||
TokenDanErin_ValidExamplePolicy = mustGetBundle(TokenDanErin_ValidExamplePolicyCID).Decoded
|
TokenDanErin_ValidExamplePolicy = mustGetBundle(TokenDanErin_ValidExamplePolicyCID).Decoded
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TokenErinFrank_ValidExamplePolicyCID = cid.MustParse("bafyreiatkvtvgakqcrdk6vgrv7tbq5rbeiqct52ep4plcftp2agffjyvp4")
|
TokenErinFrank_ValidExamplePolicyCID = cid.MustParse("bafyreiegytubdwqnl3gd7dddfmqhr4kyo4sb5446kjyqvvolk2wmwum6ae")
|
||||||
TokenErinFrank_ValidExamplePolicySealed = mustGetBundle(TokenErinFrank_ValidExamplePolicyCID).Sealed
|
TokenErinFrank_ValidExamplePolicySealed = mustGetBundle(TokenErinFrank_ValidExamplePolicyCID).Sealed
|
||||||
TokenErinFrank_ValidExamplePolicyBundle = mustGetBundle(TokenErinFrank_ValidExamplePolicyCID)
|
TokenErinFrank_ValidExamplePolicyBundle = mustGetBundle(TokenErinFrank_ValidExamplePolicyCID)
|
||||||
TokenErinFrank_ValidExamplePolicy = mustGetBundle(TokenErinFrank_ValidExamplePolicyCID).Decoded
|
TokenErinFrank_ValidExamplePolicy = mustGetBundle(TokenErinFrank_ValidExamplePolicyCID).Decoded
|
||||||
@@ -195,7 +195,7 @@ var AllTokens = []*delegation.Token{
|
|||||||
TokenErinFrank_ValidExamplePolicy,
|
TokenErinFrank_ValidExamplePolicy,
|
||||||
}
|
}
|
||||||
|
|
||||||
var AllBundles = []*delegation.Bundle{
|
var AllBundles = []delegation.Bundle{
|
||||||
TokenAliceBobBundle,
|
TokenAliceBobBundle,
|
||||||
TokenBobCarolBundle,
|
TokenBobCarolBundle,
|
||||||
TokenCarolDanBundle,
|
TokenCarolDanBundle,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation/delegationtest"
|
"code.sonr.org/go/ucan/token/delegation/delegationtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetDelegation(t *testing.T) {
|
func TestGetDelegation(t *testing.T) {
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it/didtest"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did/didtest"
|
"code.sonr.org/go/ucan/pkg/command"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/command"
|
"code.sonr.org/go/ucan/pkg/policy"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy"
|
"code.sonr.org/go/ucan/pkg/policy/literal"
|
||||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
"code.sonr.org/go/ucan/token/internal/envelope"
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/envelope"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The following example shows how to create a delegation.Token with
|
// The following example shows how to create a delegation.Token with
|
||||||
@@ -57,37 +57,37 @@ func ExampleNew() {
|
|||||||
|
|
||||||
// Example output:
|
// Example output:
|
||||||
//
|
//
|
||||||
// issDid: did:key:z6MkvJPmEZZYbgiw1ouT1oouTsTFBHJSts9ophVsNgcRmYxU
|
// issDid: did:key:z6Mkf4WtCwPDtamsZvBJA4eSVcE7vZuRPy5Skm4HaoQv81i1
|
||||||
//
|
//
|
||||||
// CID (base58BTC): zdpuAsqfZkgg2jgZyob23sq1J9xwtf9PHgt1PsskVCMq7Vvxk
|
// CID (base58BTC): zdpuB1bzMdGAtzBej9ZBJbW3ppsjP2Cf9KZ8xMjdhUjaf3vz1
|
||||||
//
|
//
|
||||||
// DAG-CBOR (base64) out: lhAOnjc0bPptlI5MxRBrIK3YmAP1CxKfXOPkz6MHt/UJCx2gCN+6gXZX2N+BIJvmy8XmAO5sT2GYimiV7HlJH1AA6JhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGpY2F1ZHg4ZGlkOmtleTp6Nk1rZ3VwY2hoNUh3dUhhaFM3WXN5RThiTHVhMU1yOHAyaUtOUmh5dlN2UkFzOW5jY21kaC9mb28vYmFyY2V4cBpnROP/Y2lzc3g4ZGlkOmtleTp6Nk1rdkpQbUVaWlliZ2l3MW91VDFvb3VUc1RGQkhKU3RzOW9waFZzTmdjUm1ZeFVjbmJmGmdE1itjcG9sg4NiPT1nLnN0YXR1c2VkcmFmdINjYWxsaS5yZXZpZXdlcoNkbGlrZWYuZW1haWxtKkBleGFtcGxlLmNvbYNjYW55ZS50YWdzgmJvcoKDYj09YS5kbmV3c4NiPT1hLmVwcmVzc2NzdWJ4OGRpZDprZXk6ejZNa3V1a2syc2tEWExRbjdOSzNFaDlqTW5kWWZ2REJ4eGt0Z3BpZEpBcWI3TTNwZG1ldGGiY2Jhehh7Y2Zvb2NiYXJlbm9uY2VMv+Diy6GExIuM1eX4
|
// DAG-CBOR (base64) out: glhAQhZTTb4U1rin/oLFre618Ol5/leaP758T6EkHYfQaNmFYad7yVTer8bbM1Zp2LxrV3eEYeWkHeL3F0V3zWC/CaJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqWNhdWR4OGRpZDprZXk6ejZNa2pXRlU4SHRmTXF1V241TUVROXIyMnpXcXlDTjF2YXpHdzZnNnB6Y2l6aU5WY2NtZGgvZm9vL2JhcmNleHAaaItoW2Npc3N4OGRpZDprZXk6ejZNa2Y0V3RDd1BEdGFtc1p2QkpBNGVTVmNFN3ZadVJQeTVTa200SGFvUXY4MWkxY25iZhpoi1qHY3BvbIODYj09Zy5zdGF0dXNlZHJhZnSDY2FsbGkucmV2aWV3ZXKDZGxpa2VmLmVtYWlsbSpAZXhhbXBsZS5jb22DY2FueWUudGFnc4Jib3KCg2I9PWEuZG5ld3ODYj09YS5lcHJlc3Njc3VieDhkaWQ6a2V5Ono2TWtuVXoxbVNqNHB2UzZhVVVIZWtDSGRVUHY3SEJoRHlEQlpRMlczVnVqYzVxQ2RtZXRhomNiYXoYe2Nmb29jYmFyZW5vbmNlTHa1D4DJ78LvscA/hg==
|
||||||
// Converted to DAG-JSON out:
|
// Converted to DAG-JSON out:
|
||||||
// [
|
// [
|
||||||
// {
|
// {
|
||||||
// "/": {
|
// "/": {
|
||||||
// "bytes": "5rvl8uKmDVGvAVSt4m/0MGiXl9dZwljJJ9m2qHCoIB617l26UvMxyH5uvN9hM7ozfVATiq4mLhoGgm9IGnEEAg"
|
// "bytes": "QhZTTb4U1rin/oLFre618Ol5/leaP758T6EkHYfQaNmFYad7yVTer8bbM1Zp2LxrV3eEYeWkHeL3F0V3zWC/CQ"
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// "h": {
|
// "h": {
|
||||||
// "/": {
|
// "/": {
|
||||||
// "bytes": "NO0BcQ"
|
// "bytes": "NAHtAe0BE3E"
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// "ucan/dlg@1.0.0-rc.1": {
|
// "ucan/dlg@1.0.0-rc.1": {
|
||||||
// "aud": "did:key:z6Mkq5YmbJcTrPExNDi26imrTCpKhepjBFBSHqrBDN2ArPkv",
|
// "aud": "did:key:z6MkjWFU8HtfMquWn5MEQ9r22zWqyCN1vazGw6g6pzciziNV",
|
||||||
// "cmd": "/foo/bar",
|
// "cmd": "/foo/bar",
|
||||||
// "exp": 1728933098,
|
// "exp": 1753966683,
|
||||||
// "iss": "did:key:z6MkhVFznPeR572rTK51UjoTNpnF8cxuWfPm9oBMPr7y8ABe",
|
// "iss": "did:key:z6Mkf4WtCwPDtamsZvBJA4eSVcE7vZuRPy5Skm4HaoQv81i1",
|
||||||
// "meta": {
|
// "meta": {
|
||||||
// "baz": 123,
|
// "baz": 123,
|
||||||
// "foo": "bar"
|
// "foo": "bar"
|
||||||
// },
|
// },
|
||||||
// "nbf": 1728929558,
|
// "nbf": 1753963143,
|
||||||
// "nonce": {
|
// "nonce": {
|
||||||
// "/": {
|
// "/": {
|
||||||
// "bytes": "u0HMgJ5Y+M84I/66"
|
// "bytes": "drUPgMnvwu+xwD+G"
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// "pol": [
|
// "pol": [
|
||||||
@@ -125,7 +125,7 @@ func ExampleNew() {
|
|||||||
// ]
|
// ]
|
||||||
// ]
|
// ]
|
||||||
// ],
|
// ],
|
||||||
// "sub": "did:key:z6MktA1uBdCpq4uJBqE9jjMiLyxZBg9a6xgPPKJjMqss6Zc2"
|
// "sub": "did:key:z6MknUz1mSj4pvS6aUUHekCHdUPv7HBhDyDBZQ2W3Vujc5qC"
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// ]
|
// ]
|
||||||
@@ -166,38 +166,36 @@ func ExampleRoot() {
|
|||||||
|
|
||||||
// Example output:
|
// Example output:
|
||||||
//
|
//
|
||||||
// issDid: did:key:z6MknWJqz17Y4AfsXSJUFKomuBR4GTkViM7kJYutzTMkCyFF
|
|
||||||
//
|
|
||||||
// CID (base58BTC): zdpuAkwYz8nY7uU8j3F6wVTfFY1VEoExwvUAYBEwRWfTozddE
|
// CID (base58BTC): zdpuAkwYz8nY7uU8j3F6wVTfFY1VEoExwvUAYBEwRWfTozddE
|
||||||
//
|
//
|
||||||
// DAG-CBOR (base64) out: glhAVpW67FJ+myNi+azvnw2jivuiqXTuMrDZI2Qdaa8jE1Oi3mkjnm7DyqSQGADcomcuDslMWKmJ+OIyvbPG5PtSA6JhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGpY2F1ZHg4ZGlkOmtleTp6Nk1rdkpQbUVaWlliZ2l3MW91VDFvb3VUc1RGQkhKU3RzOW9waFZzTmdjUm1ZeFVjY21kaC9mb28vYmFyY2V4cBpnROVoY2lzc3g4ZGlkOmtleTp6Nk1rdXVrazJza0RYTFFuN05LM0VoOWpNbmRZZnZEQnh4a3RncGlkSkFxYjdNM3BjbmJmGmdE15RjcG9sg4NiPT1nLnN0YXR1c2VkcmFmdINjYWxsaS5yZXZpZXdlcoNkbGlrZWYuZW1haWxtKkBleGFtcGxlLmNvbYNjYW55ZS50YWdzgmJvcoKDYj09YS5kbmV3c4NiPT1hLmVwcmVzc2NzdWJ4OGRpZDprZXk6ejZNa3V1a2syc2tEWExRbjdOSzNFaDlqTW5kWWZ2REJ4eGt0Z3BpZEpBcWI3TTNwZG1ldGGiY2Jhehh7Y2Zvb2NiYXJlbm9uY2VMwzDc03WBciJIGPWG
|
// DAG-CBOR (base64) out: glhATIXb2wnBByq/llaQ4RLoWTxheAwamCNo2sKL8SQJbq0EVRvdfUQDKNpuMVkvtyUR6tUdZlKv1BcXjfGEaF2XAKJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xqWNhdWR4OGRpZDprZXk6ejZNa2Y0V3RDd1BEdGFtc1p2QkpBNGVTVmNFN3ZadVJQeTVTa200SGFvUXY4MWkxY2NtZGgvZm9vL2JhcmNleHAaaItnfWNpc3N4OGRpZDprZXk6ejZNa25VejFtU2o0cHZTNmFVVUhla0NIZFVQdjdIQmhEeURCWlEyVzNWdWpjNXFDY25iZhpoi1mpY3BvbIODYj09Zy5zdGF0dXNlZHJhZnSDY2FsbGkucmV2aWV3ZXKDZGxpa2VmLmVtYWlsbSpAZXhhbXBsZS5jb22DY2FueWUudGFnc4Jib3KCg2I9PWEuZG5ld3ODYj09YS5lcHJlc3Njc3VieDhkaWQ6a2V5Ono2TWtuVXoxbVNqNHB2UzZhVVVIZWtDSGRVUHY3SEJoRHlEQlpRMlczVnVqYzVxQ2RtZXRhomNiYXoYe2Nmb29jYmFyZW5vbmNlTGxwbjHKcevt5dZ0Xg==
|
||||||
//
|
//
|
||||||
// Converted to DAG-JSON out:
|
// Converted to DAG-JSON out:
|
||||||
// [
|
// [
|
||||||
// {
|
// {
|
||||||
// "/": {
|
// "/": {
|
||||||
// "bytes": "VpW67FJ+myNi+azvnw2jivuiqXTuMrDZI2Qdaa8jE1Oi3mkjnm7DyqSQGADcomcuDslMWKmJ+OIyvbPG5PtSAw"
|
// "bytes": "TIXb2wnBByq/llaQ4RLoWTxheAwamCNo2sKL8SQJbq0EVRvdfUQDKNpuMVkvtyUR6tUdZlKv1BcXjfGEaF2XAA"
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// "h": {
|
// "h": {
|
||||||
// "/": {
|
// "/": {
|
||||||
// "bytes": "NO0BcQ"
|
// "bytes": "NAHtAe0BE3E"
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// "ucan/dlg@1.0.0-rc.1": {
|
// "ucan/dlg@1.0.0-rc.1": {
|
||||||
// "aud": "did:key:z6MkvJPmEZZYbgiw1ouT1oouTsTFBHJSts9ophVsNgcRmYxU",
|
// "aud": "did:key:z6Mkf4WtCwPDtamsZvBJA4eSVcE7vZuRPy5Skm4HaoQv81i1",
|
||||||
// "cmd": "/foo/bar",
|
// "cmd": "/foo/bar",
|
||||||
// "exp": 1732568424,
|
// "exp": 1753966461,
|
||||||
// "iss": "did:key:z6Mkuukk2skDXLQn7NK3Eh9jMndYfvDBxxktgpidJAqb7M3p",
|
// "iss": "did:key:z6MknUz1mSj4pvS6aUUHekCHdUPv7HBhDyDBZQ2W3Vujc5qC",
|
||||||
// "meta": {
|
// "meta": {
|
||||||
// "baz": 123,
|
// "baz": 123,
|
||||||
// "foo": "bar"
|
// "foo": "bar"
|
||||||
// },
|
// },
|
||||||
// "nbf": 1732564884,
|
// "nbf": 1753962921,
|
||||||
// "nonce": {
|
// "nonce": {
|
||||||
// "/": {
|
// "/": {
|
||||||
// "bytes": "wzDc03WBciJIGPWG"
|
// "bytes": "bHBuMcpx6+3l1nRe"
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// "pol": [
|
// "pol": [
|
||||||
@@ -235,7 +233,7 @@ func ExampleRoot() {
|
|||||||
// ]
|
// ]
|
||||||
// ]
|
// ]
|
||||||
// ],
|
// ],
|
||||||
// "sub": "did:key:z6Mkuukk2skDXLQn7NK3Eh9jMndYfvDBxxktgpidJAqb7M3p"
|
// "sub": "did:key:z6MknUz1mSj4pvS6aUUHekCHdUPv7HBhDyDBZQ2W3Vujc5qC"
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// ]
|
// ]
|
||||||
@@ -244,7 +242,7 @@ func ExampleRoot() {
|
|||||||
// The following example demonstrates how to get a delegation.Token from
|
// The following example demonstrates how to get a delegation.Token from
|
||||||
// a DAG-CBOR []byte.
|
// a DAG-CBOR []byte.
|
||||||
func ExampleFromSealed() {
|
func ExampleFromSealed() {
|
||||||
const cborBase64 = "glhAmnAkgfjAx4SA5pzJmtaHRJtTGNpF1y6oqb4yhGoM2H2EUGbBYT4rVDjMKBgCjhdGHjipm00L8iR5SsQh3sIEBaJhaEQ07QFxc3VjYW4vZGxnQDEuMC4wLXJjLjGoY2F1ZHg4ZGlkOmtleTp6Nk1rcTVZbWJKY1RyUEV4TkRpMjZpbXJUQ3BLaGVwakJGQlNIcXJCRE4yQXJQa3ZjY21kaC9mb28vYmFyY2V4cPZjaXNzeDhkaWQ6a2V5Ono2TWtwem4ybjNaR1QyVmFxTUdTUUMzdHptelY0VFM5UzcxaUZzRFhFMVdub05IMmNwb2yDg2I9PWcuc3RhdHVzZWRyYWZ0g2NhbGxpLnJldmlld2Vyg2RsaWtlZi5lbWFpbG0qQGV4YW1wbGUuY29tg2NhbnllLnRhZ3OCYm9ygoNiPT1hLmRuZXdzg2I9PWEuZXByZXNzY3N1Yng4ZGlkOmtleTp6Nk1rdEExdUJkQ3BxNHVKQnFFOWpqTWlMeXhaQmc5YTZ4Z1BQS0pqTXFzczZaYzJkbWV0YaBlbm9uY2VMAAECAwQFBgcICQoL"
|
const cborBase64 = "glhACBuW/rjVKyBPUVPxexsafwBe7y84k0yzywq3hQW2rs2TNmWA5wexAQ+jTkSQ07zhmQRA/wytBfqWkx24+sjlD6JhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xp2NhdWR4OGRpZDprZXk6ejZNa2pXRlU4SHRmTXF1V241TUVROXIyMnpXcXlDTjF2YXpHdzZnNnB6Y2l6aU5WY2NtZGgvZm9vL2JhcmNleHD2Y2lzc3g4ZGlkOmtleTp6Nk1rZjRXdEN3UER0YW1zWnZCSkE0ZVNWY0U3dlp1UlB5NVNrbTRIYW9RdjgxaTFjcG9sg4NiPT1nLnN0YXR1c2VkcmFmdINjYWxsaS5yZXZpZXdlcoNkbGlrZWYuZW1haWxtKkBleGFtcGxlLmNvbYNjYW55ZS50YWdzgmJvcoKDYj09YS5kbmV3c4NiPT1hLmVwcmVzc2NzdWJ4OGRpZDprZXk6ejZNa25VejFtU2o0cHZTNmFVVUhla0NIZFVQdjdIQmhEeURCWlEyVzNWdWpjNXFDZW5vbmNlTDVJDkO3LVTKnhxKKw=="
|
||||||
|
|
||||||
cborBytes, err := base64.StdEncoding.DecodeString(cborBase64)
|
cborBytes, err := base64.StdEncoding.DecodeString(cborBase64)
|
||||||
printThenPanicOnErr(err)
|
printThenPanicOnErr(err)
|
||||||
@@ -264,22 +262,24 @@ func ExampleFromSealed() {
|
|||||||
fmt.Println("Expiration (exp):", tkn.Expiration())
|
fmt.Println("Expiration (exp):", tkn.Expiration())
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// CID (base58BTC): zdpuAw26pFuvZa2Z9YAtpZZnWN6VmnRFr7Z8LVY5c7RVWoxGY
|
// CID (base58BTC): zdpuAsgmtmC849BEApGCJm2fTSzwtHiAqQnuJCMBBBCbFiadd
|
||||||
// Issuer (iss): did:key:z6Mkpzn2n3ZGT2VaqMGSQC3tzmzV4TS9S71iFsDXE1WnoNH2
|
// Issuer (iss): did:key:z6Mkf4WtCwPDtamsZvBJA4eSVcE7vZuRPy5Skm4HaoQv81i1
|
||||||
// Audience (aud): did:key:z6Mkq5YmbJcTrPExNDi26imrTCpKhepjBFBSHqrBDN2ArPkv
|
// Audience (aud): did:key:z6MkjWFU8HtfMquWn5MEQ9r22zWqyCN1vazGw6g6pzciziNV
|
||||||
// Subject (sub): did:key:z6MktA1uBdCpq4uJBqE9jjMiLyxZBg9a6xgPPKJjMqss6Zc2
|
// Subject (sub): did:key:z6MknUz1mSj4pvS6aUUHekCHdUPv7HBhDyDBZQ2W3Vujc5qC
|
||||||
// Command (cmd): /foo/bar
|
// Command (cmd): /foo/bar
|
||||||
// Policy (pol): [
|
// Policy (pol): [
|
||||||
// ["==", ".status", "draft"],
|
// ["==", ".status", "draft"],
|
||||||
// ["all", ".reviewer",
|
// ["all", ".reviewer",
|
||||||
// ["like", ".email", "*@example.com"]],
|
// ["like", ".email", "*@example.com"]
|
||||||
|
// ],
|
||||||
// ["any", ".tags",
|
// ["any", ".tags",
|
||||||
// ["or", [
|
// ["or", [
|
||||||
// ["==", ".", "news"],
|
// ["==", ".", "news"],
|
||||||
// ["==", ".", "press"]]]
|
// ["==", ".", "press"]
|
||||||
|
// ]]
|
||||||
// ]
|
// ]
|
||||||
// ]
|
// ]
|
||||||
// Nonce (nonce): 000102030405060708090a0b
|
// Nonce (nonce): 35490e43b72d54ca9e1c4a2b
|
||||||
// Meta (meta): {}
|
// Meta (meta): {}
|
||||||
// NotBefore (nbf): <nil>
|
// NotBefore (nbf): <nil>
|
||||||
// Expiration (exp): <nil>
|
// Expiration (exp): <nil>
|
||||||
|
|||||||
108
token/delegation/interop_test.go
Normal file
108
token/delegation/interop_test.go
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package delegation
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it/crypto"
|
||||||
|
"code.sonr.org/go/did-it/crypto/ed25519"
|
||||||
|
"github.com/multiformats/go-varint"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This comes from https://github.com/ucan-wg/spec/blob/main/fixtures/1.0.0/delegation.json
|
||||||
|
//
|
||||||
|
//go:embed testdata/interop_delegation.json
|
||||||
|
var interopDelegation []byte
|
||||||
|
|
||||||
|
type interop struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
Comments string `json:"comments"`
|
||||||
|
Principals map[string]string `json:"principals"`
|
||||||
|
Valid []validTestCase `json:"valid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type validTestCase struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
CID string `json:"cid"`
|
||||||
|
Envelope envelopeData `json:"envelope"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type envelopeData struct {
|
||||||
|
Payload payloadData `json:"payload"`
|
||||||
|
Signature string `json:"signature"`
|
||||||
|
Algorithm string `json:"alg"`
|
||||||
|
Encoding string `json:"enc"`
|
||||||
|
Spec string `json:"spec"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type payloadData struct {
|
||||||
|
Issuer string `json:"iss"`
|
||||||
|
Audience string `json:"aud"`
|
||||||
|
Subject string `json:"sub"`
|
||||||
|
Command string `json:"cmd"`
|
||||||
|
Policies json.RawMessage `json:"pol"`
|
||||||
|
ExpiresAt int64 `json:"exp"`
|
||||||
|
Nonce string `json:"nonce"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInterop(t *testing.T) {
|
||||||
|
var testData interop
|
||||||
|
err := json.Unmarshal(interopDelegation, &testData)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, "1.0.0-rc.1", testData.Version)
|
||||||
|
|
||||||
|
// alice, err := decodeKey(testData.Principals["alice"])
|
||||||
|
// require.NoError(t, err)
|
||||||
|
// bob, err := decodeKey(testData.Principals["bob"])
|
||||||
|
// require.NoError(t, err)
|
||||||
|
// carol, err := decodeKey(testData.Principals["carol"])
|
||||||
|
// require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Run("valid", func(t *testing.T) {
|
||||||
|
for _, tc := range testData.Valid {
|
||||||
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
dlgBytes, err := base64.StdEncoding.DecodeString(tc.Token)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dlg, c, err := FromSealed(dlgBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tc.CID, c.String())
|
||||||
|
|
||||||
|
require.Equal(t, tc.Envelope.Payload.Issuer, dlg.Issuer().String())
|
||||||
|
require.Equal(t, tc.Envelope.Payload.Audience, dlg.Audience().String())
|
||||||
|
require.Equal(t, tc.Envelope.Payload.Subject, dlg.Subject().String())
|
||||||
|
require.Equal(t, tc.Envelope.Payload.Command, dlg.Command().String())
|
||||||
|
require.Equal(t, tc.Envelope.Payload.Command, dlg.Command().String())
|
||||||
|
require.JSONEq(t, string(tc.Envelope.Payload.Policies), dlg.Policy().String())
|
||||||
|
require.Equal(t, tc.Envelope.Payload.ExpiresAt, dlg.expiration.Unix())
|
||||||
|
nonceBytes, err := base64.StdEncoding.DecodeString(tc.Envelope.Payload.Nonce)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, nonceBytes, dlg.Nonce())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeKey(key string) (crypto.PrivateKeySigningBytes, error) {
|
||||||
|
bytes, err := base64.StdEncoding.DecodeString(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
code, read, err := varint.FromUvarint(bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if code != 0x1300 {
|
||||||
|
return nil, fmt.Errorf("invalid varint code: %d", code)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ed25519.PrivateKeyFromSeed(bytes[read:])
|
||||||
|
}
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
package delegation
|
package delegation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it"
|
||||||
|
"code.sonr.org/go/did-it/crypto"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/codec"
|
"github.com/ipld/go-ipld-prime/codec"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
||||||
"github.com/ipld/go-ipld-prime/datamodel"
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did"
|
"code.sonr.org/go/ucan/token/internal/envelope"
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/envelope"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ToSealed wraps the delegation token in an envelope, generates the
|
// ToSealed wraps the delegation token in an envelope, generates the
|
||||||
// signature, encodes the result to DAG-CBOR and calculates the CID of
|
// signature, encodes the result to DAG-CBOR and calculates the CID of
|
||||||
// the resulting binary data.
|
// the resulting binary data.
|
||||||
func (t *Token) ToSealed(privKey crypto.PrivKey) ([]byte, cid.Cid, error) {
|
func (t *Token) ToSealed(privKey crypto.PrivateKeySigningBytes) ([]byte, cid.Cid, error) {
|
||||||
data, err := t.ToDagCbor(privKey)
|
data, err := t.ToDagCbor(privKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cid.Undef, err
|
return nil, cid.Undef, err
|
||||||
@@ -34,7 +33,7 @@ func (t *Token) ToSealed(privKey crypto.PrivKey) ([]byte, cid.Cid, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToSealedWriter is the same as ToSealed but accepts an io.Writer.
|
// ToSealedWriter is the same as ToSealed but accepts an io.Writer.
|
||||||
func (t *Token) ToSealedWriter(w io.Writer, privKey crypto.PrivKey) (cid.Cid, error) {
|
func (t *Token) ToSealedWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes) (cid.Cid, error) {
|
||||||
cidWriter := envelope.NewCIDWriter(w)
|
cidWriter := envelope.NewCIDWriter(w)
|
||||||
|
|
||||||
if err := t.ToDagCborWriter(cidWriter, privKey); err != nil {
|
if err := t.ToDagCborWriter(cidWriter, privKey); err != nil {
|
||||||
@@ -48,8 +47,8 @@ func (t *Token) ToSealedWriter(w io.Writer, privKey crypto.PrivKey) (cid.Cid, er
|
|||||||
// verifies that the envelope's signature is correct based on the public
|
// verifies that the envelope's signature is correct based on the public
|
||||||
// key taken from the issuer (iss) field and calculates the CID of the
|
// key taken from the issuer (iss) field and calculates the CID of the
|
||||||
// incoming data.
|
// incoming data.
|
||||||
func FromSealed(data []byte) (*Token, cid.Cid, error) {
|
func FromSealed(data []byte, resolvOpts ...did.ResolutionOption) (*Token, cid.Cid, error) {
|
||||||
tkn, err := FromDagCbor(data)
|
tkn, err := FromDagCbor(data, resolvOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cid.Undef, err
|
return nil, cid.Undef, err
|
||||||
}
|
}
|
||||||
@@ -63,10 +62,10 @@ func FromSealed(data []byte) (*Token, cid.Cid, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FromSealedReader is the same as Unseal but accepts an io.Reader.
|
// FromSealedReader is the same as Unseal but accepts an io.Reader.
|
||||||
func FromSealedReader(r io.Reader) (*Token, cid.Cid, error) {
|
func FromSealedReader(r io.Reader, resolvOpts ...did.ResolutionOption) (*Token, cid.Cid, error) {
|
||||||
cidReader := envelope.NewCIDReader(r)
|
cidReader := envelope.NewCIDReader(r)
|
||||||
|
|
||||||
tkn, err := FromDagCborReader(cidReader)
|
tkn, err := FromDagCborReader(cidReader, resolvOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cid.Undef, err
|
return nil, cid.Undef, err
|
||||||
}
|
}
|
||||||
@@ -81,7 +80,7 @@ func FromSealedReader(r io.Reader) (*Token, cid.Cid, error) {
|
|||||||
|
|
||||||
// Encode marshals a Token to the format specified by the provided
|
// Encode marshals a Token to the format specified by the provided
|
||||||
// codec.Encoder.
|
// codec.Encoder.
|
||||||
func (t *Token) Encode(privKey crypto.PrivKey, encFn codec.Encoder) ([]byte, error) {
|
func (t *Token) Encode(privKey crypto.PrivateKeySigningBytes, encFn codec.Encoder) ([]byte, error) {
|
||||||
node, err := t.toIPLD(privKey)
|
node, err := t.toIPLD(privKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -91,7 +90,7 @@ func (t *Token) Encode(privKey crypto.PrivKey, encFn codec.Encoder) ([]byte, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncodeWriter is the same as Encode, but accepts an io.Writer.
|
// EncodeWriter is the same as Encode, but accepts an io.Writer.
|
||||||
func (t *Token) EncodeWriter(w io.Writer, privKey crypto.PrivKey, encFn codec.Encoder) error {
|
func (t *Token) EncodeWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes, encFn codec.Encoder) error {
|
||||||
node, err := t.toIPLD(privKey)
|
node, err := t.toIPLD(privKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -101,22 +100,22 @@ func (t *Token) EncodeWriter(w io.Writer, privKey crypto.PrivKey, encFn codec.En
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToDagCbor marshals the Token to the DAG-CBOR format.
|
// ToDagCbor marshals the Token to the DAG-CBOR format.
|
||||||
func (t *Token) ToDagCbor(privKey crypto.PrivKey) ([]byte, error) {
|
func (t *Token) ToDagCbor(privKey crypto.PrivateKeySigningBytes) ([]byte, error) {
|
||||||
return t.Encode(privKey, dagcbor.Encode)
|
return t.Encode(privKey, dagcbor.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDagCborWriter is the same as ToDagCbor, but it accepts an io.Writer.
|
// ToDagCborWriter is the same as ToDagCbor, but it accepts an io.Writer.
|
||||||
func (t *Token) ToDagCborWriter(w io.Writer, privKey crypto.PrivKey) error {
|
func (t *Token) ToDagCborWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes) error {
|
||||||
return t.EncodeWriter(w, privKey, dagcbor.Encode)
|
return t.EncodeWriter(w, privKey, dagcbor.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDagJson marshals the Token to the DAG-JSON format.
|
// ToDagJson marshals the Token to the DAG-JSON format.
|
||||||
func (t *Token) ToDagJson(privKey crypto.PrivKey) ([]byte, error) {
|
func (t *Token) ToDagJson(privKey crypto.PrivateKeySigningBytes) ([]byte, error) {
|
||||||
return t.Encode(privKey, dagjson.Encode)
|
return t.Encode(privKey, dagjson.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDagJsonWriter is the same as ToDagJson, but it accepts an io.Writer.
|
// ToDagJsonWriter is the same as ToDagJson, but it accepts an io.Writer.
|
||||||
func (t *Token) ToDagJsonWriter(w io.Writer, privKey crypto.PrivKey) error {
|
func (t *Token) ToDagJsonWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes) error {
|
||||||
return t.EncodeWriter(w, privKey, dagjson.Encode)
|
return t.EncodeWriter(w, privKey, dagjson.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,29 +124,29 @@ func (t *Token) ToDagJsonWriter(w io.Writer, privKey crypto.PrivKey) error {
|
|||||||
//
|
//
|
||||||
// An error is returned if the conversion fails, or if the resulting
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
// Token is invalid.
|
// Token is invalid.
|
||||||
func Decode(b []byte, decFn codec.Decoder) (*Token, error) {
|
func Decode(b []byte, decFn codec.Decoder, resolvOpts ...did.ResolutionOption) (*Token, error) {
|
||||||
node, err := ipld.Decode(b, decFn)
|
node, err := ipld.Decode(b, decFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return FromIPLD(node)
|
return FromIPLD(node, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeReader is the same as Decode, but accept an io.Reader.
|
// DecodeReader is the same as Decode, but accept an io.Reader.
|
||||||
func DecodeReader(r io.Reader, decFn codec.Decoder) (*Token, error) {
|
func DecodeReader(r io.Reader, decFn codec.Decoder, resolvOpts ...did.ResolutionOption) (*Token, error) {
|
||||||
node, err := ipld.DecodeStreaming(r, decFn)
|
node, err := ipld.DecodeStreaming(r, decFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return FromIPLD(node)
|
return FromIPLD(node, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromDagCbor unmarshals the input data into a Token.
|
// FromDagCbor unmarshals the input data into a Token.
|
||||||
//
|
//
|
||||||
// An error is returned if the conversion fails, or if the resulting
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
// Token is invalid.
|
// Token is invalid.
|
||||||
func FromDagCbor(data []byte) (*Token, error) {
|
func FromDagCbor(data []byte, resolvOpts ...did.ResolutionOption) (*Token, error) {
|
||||||
pay, err := envelope.FromDagCbor[*tokenPayloadModel](data)
|
pay, err := envelope.FromDagCbor[*tokenPayloadModel](data, resolvOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -161,26 +160,26 @@ func FromDagCbor(data []byte) (*Token, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FromDagCborReader is the same as FromDagCbor, but accept an io.Reader.
|
// FromDagCborReader is the same as FromDagCbor, but accept an io.Reader.
|
||||||
func FromDagCborReader(r io.Reader) (*Token, error) {
|
func FromDagCborReader(r io.Reader, resolvOpts ...did.ResolutionOption) (*Token, error) {
|
||||||
return DecodeReader(r, dagcbor.Decode)
|
return DecodeReader(r, dagcbor.Decode, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromDagJson unmarshals the input data into a Token.
|
// FromDagJson unmarshals the input data into a Token.
|
||||||
//
|
//
|
||||||
// An error is returned if the conversion fails, or if the resulting
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
// Token is invalid.
|
// Token is invalid.
|
||||||
func FromDagJson(data []byte) (*Token, error) {
|
func FromDagJson(data []byte, resolvOpts ...did.ResolutionOption) (*Token, error) {
|
||||||
return Decode(data, dagjson.Decode)
|
return Decode(data, dagjson.Decode, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromDagJsonReader is the same as FromDagJson, but accept an io.Reader.
|
// FromDagJsonReader is the same as FromDagJson, but accept an io.Reader.
|
||||||
func FromDagJsonReader(r io.Reader) (*Token, error) {
|
func FromDagJsonReader(r io.Reader, resolvOpts ...did.ResolutionOption) (*Token, error) {
|
||||||
return DecodeReader(r, dagjson.Decode)
|
return DecodeReader(r, dagjson.Decode, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromIPLD decode the given IPLD representation into a Token.
|
// FromIPLD decode the given IPLD representation into a Token.
|
||||||
func FromIPLD(node datamodel.Node) (*Token, error) {
|
func FromIPLD(node datamodel.Node, resolvOpts ...did.ResolutionOption) (*Token, error) {
|
||||||
pay, err := envelope.FromIPLD[*tokenPayloadModel](node)
|
pay, err := envelope.FromIPLD[*tokenPayloadModel](node, resolvOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -193,18 +192,9 @@ func FromIPLD(node datamodel.Node) (*Token, error) {
|
|||||||
return tkn, err
|
return tkn, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Token) toIPLD(privKey crypto.PrivKey) (datamodel.Node, error) {
|
func (t *Token) toIPLD(privKey crypto.PrivateKeySigningBytes) (datamodel.Node, error) {
|
||||||
// sanity check that privKey and issuer are matching
|
|
||||||
issPub, err := t.issuer.PubKey()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !issPub.Equals(privKey.GetPublic()) {
|
|
||||||
return nil, fmt.Errorf("private key doesn't match the issuer")
|
|
||||||
}
|
|
||||||
|
|
||||||
var sub *string
|
var sub *string
|
||||||
if t.subject != did.Undef {
|
if t.subject != nil {
|
||||||
s := t.subject.String()
|
s := t.subject.String()
|
||||||
sub = &s
|
sub = &s
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime/node/bindnode"
|
"github.com/ipld/go-ipld-prime/node/bindnode"
|
||||||
"github.com/ipld/go-ipld-prime/schema"
|
"github.com/ipld/go-ipld-prime/schema"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/pkg/meta"
|
"code.sonr.org/go/ucan/pkg/meta"
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/envelope"
|
"code.sonr.org/go/ucan/token/internal/envelope"
|
||||||
)
|
)
|
||||||
|
|
||||||
// [Tag] is the string used as a key within the SigPayload that identifies
|
// Tag is the string used as a key within the SigPayload that identifies
|
||||||
// that the TokenPayload is a delegation.
|
// that the TokenPayload is a delegation.
|
||||||
//
|
//
|
||||||
// [Tag]: https://github.com/ucan-wg/delegation/tree/v1_ipld#type-tag
|
// See: https://github.com/ucan-wg/delegation/tree/v1_ipld#type-tag
|
||||||
const Tag = "ucan/dlg@1.0.0-rc.1"
|
const Tag = "ucan/dlg@1.0.0-rc.1"
|
||||||
|
|
||||||
// TODO: update the above Tag URL once the delegation specification is merged.
|
// TODO: update the above Tag URL once the delegation specification is merged.
|
||||||
|
|||||||
@@ -5,14 +5,13 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it/didtest"
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gotest.tools/v3/golden"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did/didtest"
|
"code.sonr.org/go/ucan/token/delegation"
|
||||||
"github.com/ucan-wg/go-ucan/token/delegation"
|
"code.sonr.org/go/ucan/token/internal/envelope"
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/envelope"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed delegation.ipldsch
|
//go:embed delegation.ipldsch
|
||||||
@@ -21,7 +20,6 @@ var schemaBytes []byte
|
|||||||
func TestSchemaRoundTrip(t *testing.T) {
|
func TestSchemaRoundTrip(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
delegationJson := golden.Get(t, "new.dagjson")
|
|
||||||
privKey := didtest.PersonaAlice.PrivKey()
|
privKey := didtest.PersonaAlice.PrivKey()
|
||||||
|
|
||||||
t.Run("via buffers", func(t *testing.T) {
|
t.Run("via buffers", func(t *testing.T) {
|
||||||
@@ -30,7 +28,7 @@ func TestSchemaRoundTrip(t *testing.T) {
|
|||||||
// format: dagJson --> PayloadModel --> dagCbor --> PayloadModel --> dagJson
|
// format: dagJson --> PayloadModel --> dagCbor --> PayloadModel --> dagJson
|
||||||
// function: DecodeDagJson() Seal() Unseal() EncodeDagJson()
|
// function: DecodeDagJson() Seal() Unseal() EncodeDagJson()
|
||||||
|
|
||||||
p1, err := delegation.FromDagJson(delegationJson)
|
p1, err := delegation.FromDagJson(newDagJson)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, newCID, err := p1.ToSealed(privKey)
|
_, newCID, err := p1.ToSealed(privKey)
|
||||||
@@ -47,13 +45,13 @@ func TestSchemaRoundTrip(t *testing.T) {
|
|||||||
readJson, err := p2.ToDagJson(privKey)
|
readJson, err := p2.ToDagJson(privKey)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.JSONEq(t, string(delegationJson), string(readJson))
|
assert.JSONEq(t, string(newDagJson), string(readJson))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("via streaming", func(t *testing.T) {
|
t.Run("via streaming", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
buf := bytes.NewBuffer(delegationJson)
|
buf := bytes.NewBuffer(newDagJson)
|
||||||
|
|
||||||
// format: dagJson --> PayloadModel --> dagCbor --> PayloadModel --> dagJson
|
// format: dagJson --> PayloadModel --> dagCbor --> PayloadModel --> dagJson
|
||||||
// function: DecodeDagJson() Seal() Unseal() EncodeDagJson()
|
// function: DecodeDagJson() Seal() Unseal() EncodeDagJson()
|
||||||
@@ -77,17 +75,7 @@ func TestSchemaRoundTrip(t *testing.T) {
|
|||||||
readJson := &bytes.Buffer{}
|
readJson := &bytes.Buffer{}
|
||||||
require.NoError(t, p2.ToDagJsonWriter(readJson, privKey))
|
require.NoError(t, p2.ToDagJsonWriter(readJson, privKey))
|
||||||
|
|
||||||
assert.JSONEq(t, string(delegationJson), readJson.String())
|
assert.JSONEq(t, string(newDagJson), readJson.String())
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("fails with wrong PrivKey", func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
p1, err := delegation.FromDagJson(delegationJson)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
_, _, err = p1.ToSealed(didtest.PersonaBob.PrivKey())
|
|
||||||
require.EqualError(t, err, "private key doesn't match the issuer")
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,11 +87,10 @@ func BenchmarkSchemaLoad(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkRoundTrip(b *testing.B) {
|
func BenchmarkRoundTrip(b *testing.B) {
|
||||||
delegationJson := golden.Get(b, "new.dagjson")
|
|
||||||
privKey := didtest.PersonaAlice.PrivKey()
|
privKey := didtest.PersonaAlice.PrivKey()
|
||||||
|
|
||||||
b.Run("via buffers", func(b *testing.B) {
|
b.Run("via buffers", func(b *testing.B) {
|
||||||
p1, _ := delegation.FromDagJson(delegationJson)
|
p1, _ := delegation.FromDagJson(newDagJson)
|
||||||
cborBytes, _, _ := p1.ToSealed(privKey)
|
cborBytes, _, _ := p1.ToSealed(privKey)
|
||||||
p2, _, _ := delegation.FromSealed(cborBytes)
|
p2, _, _ := delegation.FromSealed(cborBytes)
|
||||||
|
|
||||||
@@ -112,7 +99,7 @@ func BenchmarkRoundTrip(b *testing.B) {
|
|||||||
b.Run("FromDagJson", func(b *testing.B) {
|
b.Run("FromDagJson", func(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, _ = delegation.FromDagJson(delegationJson)
|
_, _ = delegation.FromDagJson(newDagJson)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -139,7 +126,7 @@ func BenchmarkRoundTrip(b *testing.B) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
b.Run("via streaming", func(b *testing.B) {
|
b.Run("via streaming", func(b *testing.B) {
|
||||||
p1, _ := delegation.FromDagJsonReader(bytes.NewReader(delegationJson))
|
p1, _ := delegation.FromDagJsonReader(bytes.NewReader(newDagJson))
|
||||||
cborBuf := &bytes.Buffer{}
|
cborBuf := &bytes.Buffer{}
|
||||||
_, _ = p1.ToSealedWriter(cborBuf, privKey)
|
_, _ = p1.ToSealedWriter(cborBuf, privKey)
|
||||||
cborBytes := cborBuf.Bytes()
|
cborBytes := cborBuf.Bytes()
|
||||||
@@ -149,7 +136,7 @@ func BenchmarkRoundTrip(b *testing.B) {
|
|||||||
|
|
||||||
b.Run("FromDagJsonReader", func(b *testing.B) {
|
b.Run("FromDagJsonReader", func(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
reader := bytes.NewReader(delegationJson)
|
reader := bytes.NewReader(newDagJson)
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, _ = reader.Seek(0, 0)
|
_, _ = reader.Seek(0, 0)
|
||||||
_, _ = delegation.FromDagJsonReader(reader)
|
_, _ = delegation.FromDagJsonReader(reader)
|
||||||
|
|||||||
32
token/delegation/testdata/interop_delegation.json
vendored
Normal file
32
token/delegation/testdata/interop_delegation.json
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0.0-rc.1",
|
||||||
|
"comments": "Principals private keys encoded as base64pad(varint(0x1300) + privateKey) and all other binary fields are encoded as base64pad.",
|
||||||
|
"principals": {
|
||||||
|
"carol": "gCZC43QGw7ZvYQuKTtBwBy+tdjYrKf0hXU3dd+J0HON5dw==",
|
||||||
|
"bob": "gCZfj9+RzU2U518TMBNK/fjdGQz34sB4iKE6z+9lQDpCIQ==",
|
||||||
|
"alice": "gCa9UfZv+yI5/rvUIt21DaGI7EZJlzFO1uDc5AyJ30c6/w=="
|
||||||
|
},
|
||||||
|
"valid": [
|
||||||
|
{
|
||||||
|
"name": "basic delegation bob > carol",
|
||||||
|
"token": "glhAd7jvZs44lTWmjSG/PWBRXvAdJA6Pq0fj86WQOVBYSw3fLrpjF7OMvjUlTynZZblPHzFsiBeBlUqtbCAHvhppCaJhaEg0Ae0B7QETcXN1Y2FuL2RsZ0AxLjAuMC1yYy4xp2NhdWR4OGRpZDprZXk6ejZNa21KY2VWb1FTSHM0NWNSZUVYb0x0V20xd29zQ0c4Ukx4Zkt3aHhvcXpvVGtDY2NtZGgvYWNjb3VudGNleHAaaIIMsWNpc3N4OGRpZDprZXk6ejZNa21UOWo2ZlZacXpYVjh1MndWVlN1NDlnWVNSWUdTUW5kdVdYRjZmb0FKcnF6Y3BvbIBjc3VieDhkaWQ6a2V5Ono2TWttVDlqNmZWWnF6WFY4dTJ3VlZTdTQ5Z1lTUllHU1FuZHVXWEY2Zm9BSnJxemVub25jZUwnbSv2keQn/Kg2KsM=",
|
||||||
|
"cid": "bafyreifqsojs54lpxxyx5xfqxiwkc4paglcyqd7vjzrcyapxi557extz6m",
|
||||||
|
"envelope": {
|
||||||
|
"payload": {
|
||||||
|
"iss": "did:key:z6MkmT9j6fVZqzXV8u2wVVSu49gYSRYGSQnduWXF6foAJrqz",
|
||||||
|
"aud": "did:key:z6MkmJceVoQSHs45cReEXoLtWm1wosCG8RLxfKwhxoqzoTkC",
|
||||||
|
"sub": "did:key:z6MkmT9j6fVZqzXV8u2wVVSu49gYSRYGSQnduWXF6foAJrqz",
|
||||||
|
"cmd": "/account",
|
||||||
|
"pol": [],
|
||||||
|
"exp": 1753353393,
|
||||||
|
"nonce": "J20r9pHkJ/yoNirD"
|
||||||
|
},
|
||||||
|
"signature": "d7jvZs44lTWmjSG/PWBRXvAdJA6Pq0fj86WQOVBYSw3fLrpjF7OMvjUlTynZZblPHzFsiBeBlUqtbCAHvhppCQ==",
|
||||||
|
"alg": "Ed25519",
|
||||||
|
"enc": "DAG-CBOR",
|
||||||
|
"spec": "dlg",
|
||||||
|
"version": "1.0.0-rc.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
2
token/delegation/testdata/new.dagjson
vendored
2
token/delegation/testdata/new.dagjson
vendored
@@ -1 +1 @@
|
|||||||
[{"/":{"bytes":"YJsl8EMLnXSFE/nKKjMxz9bHHo+Y7QeLEzukEzW1TB+m53TTiY1aOt+qUO8JaTcOKsOHt/a4Vn+YiOd5CkLdAQ"}},{"h":{"/":{"bytes":"NO0BcQ"}},"ucan/dlg@1.0.0-rc.1":{"aud":"did:key:z6MkvJPmEZZYbgiw1ouT1oouTsTFBHJSts9ophVsNgcRmYxU","cmd":"/foo/bar","exp":7258118400,"iss":"did:key:z6Mkuukk2skDXLQn7NK3Eh9jMndYfvDBxxktgpidJAqb7M3p","meta":{"bar":"barr","foo":"fooo"},"nonce":{"/":{"bytes":"NnJvRGhHaTBraU5yaVFBejdKM2QrYk9lb0kvdGo4RU5pa21RTmJ0am5EMA"}},"pol":[["==",".status","draft"],["all",".reviewer",["like",".email","*@example.com"]],["any",".tags",["or",[["==",".","news"],["==",".","press"]]]]],"sub":"did:key:z6Mkgupchh5HwuHahS7YsyE8bLua1Mr8p2iKNRhyvSvRAs9n"}}]
|
[{"/":{"bytes":"7Df/QlkgvQ/j1sr2NUFryQbTxo16rsOPfDPX8evBmA0hV6Omv+sScM8HC30KHr/kXCl+DzxDg+/EOwiZ9ApNBQ"}},{"h":{"/":{"bytes":"NAHtAe0BE3E"}},"ucan/dlg@1.0.0-rc.1":{"aud":"did:key:z6Mkf4WtCwPDtamsZvBJA4eSVcE7vZuRPy5Skm4HaoQv81i1","cmd":"/foo/bar","exp":7258118400,"iss":"did:key:z6MknUz1mSj4pvS6aUUHekCHdUPv7HBhDyDBZQ2W3Vujc5qC","meta":{"bar":"barr","foo":"fooo"},"nonce":{"/":{"bytes":"NnJvRGhHaTBraU5yaVFBejdKM2QrYk9lb0kvdGo4RU5pa21RTmJ0am5EMA"}},"pol":[["==",".status","draft"],["all",".reviewer",["like",".email","*@example.com"]],["any",".tags",["or",[["==",".","news"],["==",".","press"]]]]],"sub":"did:key:z6MkjWFU8HtfMquWn5MEQ9r22zWqyCN1vazGw6g6pzciziNV"}}]
|
||||||
2
token/delegation/testdata/powerline.dagjson
vendored
2
token/delegation/testdata/powerline.dagjson
vendored
@@ -1 +1 @@
|
|||||||
[{"/":{"bytes":"i3YkPDvNSU4V8XYEluZhLH0b+NDcW/6+PtPSUHC17cmXXqgelG0K4EzWQQkS9UsYCHfkZSCn9NjGSXYMMFhaAQ"}},{"h":{"/":{"bytes":"NO0BcQ"}},"ucan/dlg@1.0.0-rc.1":{"aud":"did:key:z6MkvJPmEZZYbgiw1ouT1oouTsTFBHJSts9ophVsNgcRmYxU","cmd":"/foo/bar","exp":7258118400,"iss":"did:key:z6Mkuukk2skDXLQn7NK3Eh9jMndYfvDBxxktgpidJAqb7M3p","meta":{"bar":"barr","foo":"fooo"},"nonce":{"/":{"bytes":"NnJvRGhHaTBraU5yaVFBejdKM2QrYk9lb0kvdGo4RU5pa21RTmJ0am5EMA"}},"pol":[["==",".status","draft"],["all",".reviewer",["like",".email","*@example.com"]],["any",".tags",["or",[["==",".","news"],["==",".","press"]]]]]}}]
|
[{"/":{"bytes":"pcdEo4gSPlBWE1kQUUjFOQNRLvXDw6BTLmgoIrU/o1JCAeSYiiIQFrHB1KIm0phZfMHqp5O6k6QxHuldxUARBQ"}},{"h":{"/":{"bytes":"NAHtAe0BE3E"}},"ucan/dlg@1.0.0-rc.1":{"aud":"did:key:z6Mkf4WtCwPDtamsZvBJA4eSVcE7vZuRPy5Skm4HaoQv81i1","cmd":"/foo/bar","exp":7258118400,"iss":"did:key:z6MknUz1mSj4pvS6aUUHekCHdUPv7HBhDyDBZQ2W3Vujc5qC","meta":{"bar":"barr","foo":"fooo"},"nonce":{"/":{"bytes":"NnJvRGhHaTBraU5yaVFBejdKM2QrYk9lb0kvdGo4RU5pa21RTmJ0am5EMA"}},"pol":[["==",".status","draft"],["all",".reviewer",["like",".email","*@example.com"]],["any",".tags",["or",[["==",".","news"],["==",".","press"]]]]]}}]
|
||||||
2
token/delegation/testdata/root.dagjson
vendored
2
token/delegation/testdata/root.dagjson
vendored
@@ -1 +1 @@
|
|||||||
[{"/":{"bytes":"BBabgnWqd+cjwG1td0w9BudNocmUwoR89RMZTqZHk3osCXEI/bOkko0zTvlusaE4EMBBeSzZDKzjvunLBfdiBg"}},{"h":{"/":{"bytes":"NO0BcQ"}},"ucan/dlg@1.0.0-rc.1":{"aud":"did:key:z6MkvJPmEZZYbgiw1ouT1oouTsTFBHJSts9ophVsNgcRmYxU","cmd":"/foo/bar","exp":7258118400,"iss":"did:key:z6Mkuukk2skDXLQn7NK3Eh9jMndYfvDBxxktgpidJAqb7M3p","meta":{"bar":"barr","foo":"fooo"},"nonce":{"/":{"bytes":"NnJvRGhHaTBraU5yaVFBejdKM2QrYk9lb0kvdGo4RU5pa21RTmJ0am5EMA"}},"pol":[["==",".status","draft"],["all",".reviewer",["like",".email","*@example.com"]],["any",".tags",["or",[["==",".","news"],["==",".","press"]]]]],"sub":"did:key:z6Mkuukk2skDXLQn7NK3Eh9jMndYfvDBxxktgpidJAqb7M3p"}}]
|
[{"/":{"bytes":"jS5WzBU0JybWoQAJjJTgxke5U7vbwOJTYbe3bipYbmhz3Lcrl1B/68dK4xhWSv6wc3zZqXFJ7/Kw2jDLCOZWDA"}},{"h":{"/":{"bytes":"NAHtAe0BE3E"}},"ucan/dlg@1.0.0-rc.1":{"aud":"did:key:z6Mkf4WtCwPDtamsZvBJA4eSVcE7vZuRPy5Skm4HaoQv81i1","cmd":"/foo/bar","exp":7258118400,"iss":"did:key:z6MknUz1mSj4pvS6aUUHekCHdUPv7HBhDyDBZQ2W3Vujc5qC","meta":{"bar":"barr","foo":"fooo"},"nonce":{"/":{"bytes":"NnJvRGhHaTBraU5yaVFBejdKM2QrYk9lb0kvdGo4RU5pa21RTmJ0am5EMA"}},"pol":[["==",".status","draft"],["all",".reviewer",["like",".email","*@example.com"]],["any",".tags",["or",[["==",".","news"],["==",".","press"]]]]],"sub":"did:key:z6MknUz1mSj4pvS6aUUHekCHdUPv7HBhDyDBZQ2W3Vujc5qC"}}]
|
||||||
@@ -16,7 +16,7 @@ type Loader interface {
|
|||||||
GetDelegation(cid cid.Cid) (*Token, error)
|
GetDelegation(cid cid.Cid) (*Token, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bundle carries together a decoded delegation with its Cid and raw signed data.
|
// Bundle carries together a decoded token with its Cid and raw signed data.
|
||||||
type Bundle struct {
|
type Bundle struct {
|
||||||
Cid cid.Cid
|
Cid cid.Cid
|
||||||
Decoded *Token
|
Decoded *Token
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package token
|
|||||||
import (
|
import (
|
||||||
"github.com/ipld/go-ipld-prime/datamodel"
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/envelope"
|
"code.sonr.org/go/ucan/token/internal/envelope"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Info = envelope.Info
|
type Info = envelope.Info
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it/crypto"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipld/go-ipld-prime/codec"
|
"github.com/ipld/go-ipld-prime/codec"
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Token interface {
|
type Token interface {
|
||||||
@@ -15,7 +15,7 @@ type Token interface {
|
|||||||
// IsValidNow verifies that the token can be used at the current time, based on expiration or "not before" fields.
|
// IsValidNow verifies that the token can be used at the current time, based on expiration or "not before" fields.
|
||||||
// This does NOT do any other kind of verifications.
|
// This does NOT do any other kind of verifications.
|
||||||
IsValidNow() bool
|
IsValidNow() bool
|
||||||
// IsValidNow verifies that the token can be used at the given time, based on expiration or "not before" fields.
|
// IsValidAt verifies that the token can be used at the given time, based on expiration or "not before" fields.
|
||||||
// This does NOT do any other kind of verifications.
|
// This does NOT do any other kind of verifications.
|
||||||
IsValidAt(t time.Time) bool
|
IsValidAt(t time.Time) bool
|
||||||
}
|
}
|
||||||
@@ -23,19 +23,26 @@ type Token interface {
|
|||||||
type Marshaller interface {
|
type Marshaller interface {
|
||||||
// ToSealed wraps the token in an envelope, generates the signature, encodes
|
// ToSealed wraps the token in an envelope, generates the signature, encodes
|
||||||
// the result to DAG-CBOR and calculates the CID of the resulting binary data.
|
// the result to DAG-CBOR and calculates the CID of the resulting binary data.
|
||||||
ToSealed(privKey crypto.PrivKey) ([]byte, cid.Cid, error)
|
ToSealed(privKey crypto.PrivateKeySigningBytes) ([]byte, cid.Cid, error)
|
||||||
// ToSealedWriter is the same as ToSealed but accepts an io.Writer.
|
// ToSealedWriter is the same as ToSealed but accepts an io.Writer.
|
||||||
ToSealedWriter(w io.Writer, privKey crypto.PrivKey) (cid.Cid, error)
|
ToSealedWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes) (cid.Cid, error)
|
||||||
// Encode marshals a Token to the format specified by the provided codec.Encoder.
|
// Encode marshals a Token to the format specified by the provided codec.Encoder.
|
||||||
Encode(privKey crypto.PrivKey, encFn codec.Encoder) ([]byte, error)
|
Encode(privKey crypto.PrivateKeySigningBytes, encFn codec.Encoder) ([]byte, error)
|
||||||
// EncodeWriter is the same as Encode, but accepts an io.Writer.
|
// EncodeWriter is the same as Encode, but accepts an io.Writer.
|
||||||
EncodeWriter(w io.Writer, privKey crypto.PrivKey, encFn codec.Encoder) error
|
EncodeWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes, encFn codec.Encoder) error
|
||||||
// ToDagCbor marshals the Token to the DAG-CBOR format.
|
// ToDagCbor marshals the Token to the DAG-CBOR format.
|
||||||
ToDagCbor(privKey crypto.PrivKey) ([]byte, error)
|
ToDagCbor(privKey crypto.PrivateKeySigningBytes) ([]byte, error)
|
||||||
// ToDagCborWriter is the same as ToDagCbor, but it accepts an io.Writer.
|
// ToDagCborWriter is the same as ToDagCbor, but it accepts an io.Writer.
|
||||||
ToDagCborWriter(w io.Writer, privKey crypto.PrivKey) error
|
ToDagCborWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes) error
|
||||||
// ToDagJson marshals the Token to the DAG-JSON format.
|
// ToDagJson marshals the Token to the DAG-JSON format.
|
||||||
ToDagJson(privKey crypto.PrivKey) ([]byte, error)
|
ToDagJson(privKey crypto.PrivateKeySigningBytes) ([]byte, error)
|
||||||
// ToDagJsonWriter is the same as ToDagJson, but it accepts an io.Writer.
|
// ToDagJsonWriter is the same as ToDagJson, but it accepts an io.Writer.
|
||||||
ToDagJsonWriter(w io.Writer, privKey crypto.PrivKey) error
|
ToDagJsonWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bundle carries together a decoded token with its Cid and raw signed data.
|
||||||
|
type Bundle struct {
|
||||||
|
Cid cid.Cid
|
||||||
|
Decoded Token
|
||||||
|
Sealed []byte
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,19 +9,18 @@ import (
|
|||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gotest.tools/v3/golden"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/envelope"
|
"code.sonr.org/go/ucan/token/internal/envelope"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCidFromBytes(t *testing.T) {
|
func TestCidFromBytes(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
expData := golden.Get(t, "example.dagcbor")
|
expData := exampleDagCbor
|
||||||
expHash, err := multihash.Sum(expData, uint64(multicodec.Sha2_256), -1)
|
expHash, err := multihash.Sum(expData, uint64(multicodec.Sha2_256), -1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
data, err := envelope.ToDagCbor(examplePrivKey(t), newExample(t))
|
data, err := envelope.ToDagCbor(examplePrivKey(t), newExample())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
id, err := envelope.CIDFromBytes(data)
|
id, err := envelope.CIDFromBytes(data)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.sonr.org/go/did-it/crypto"
|
||||||
|
"code.sonr.org/go/did-it/crypto/ed25519"
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
||||||
"github.com/ipld/go-ipld-prime/datamodel"
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
@@ -14,32 +16,30 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime/node/basicnode"
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
||||||
"github.com/ipld/go-ipld-prime/node/bindnode"
|
"github.com/ipld/go-ipld-prime/node/bindnode"
|
||||||
"github.com/ipld/go-ipld-prime/schema"
|
"github.com/ipld/go-ipld-prime/schema"
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gotest.tools/v3/golden"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/envelope"
|
"code.sonr.org/go/ucan/token/internal/envelope"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
exampleCID = "zdpuAyw6R5HvKSPzztuzXNYFx3ZGoMHMuAsXL6u3xLGQriRXQ"
|
exampleCID = "zdpuAn4jksvc1gc9PLDqHw2NoFq8CBkRVTTo2xFuW2JUPS5DY"
|
||||||
exampleDID = "did:key:z6MkpuK2Amsu1RqcLGgmHHQHhvmeXCCBVsM4XFSg2cCyg4Nh"
|
exampleDID = "did:key:z6MkuqvEtTW9L1E91CY3GmL83muetLAA2h8A5fUHjJgqq2Ab"
|
||||||
exampleGreeting = "world"
|
exampleGreeting = "world"
|
||||||
examplePrivKeyCfg = "CAESQP9v2uqECTuIi45dyg3znQvsryvf2IXmOF/6aws6aCehm0FVrj0zHR5RZSDxWNjcpcJqsGym3sjCungX9Zt5oA4="
|
examplePrivKeyB64 = "V4hh1lcFV43Y6vyOBEVOFTwl1XS/DR0F/kYcz5i6W/DkrUTG8yx09lOwSf36NCHPKSFYv/T1R3WKjNfndgVucA=="
|
||||||
exampleSignatureStr = "PZV6A2aI7n+MlyADqcqmWhkuyNrgUCDz+qSLSnI9bpasOwOhKUTx95m5Nu5CO/INa1LqzHGioD9+PVf6qdtTBg"
|
|
||||||
exampleTag = "ucan/example@v1.0.0-rc.1"
|
exampleTag = "ucan/example@v1.0.0-rc.1"
|
||||||
exampleTypeName = "Example"
|
|
||||||
exampleVarsigHeaderStr = "NO0BcQ"
|
|
||||||
|
|
||||||
invalidSignatureStr = "PZV6A2aI7n+MlyADqcqmWhkuyNrgUCDz+qSLSnI9bpasOwOhKUTx95m5Nu5CO/INa1LqzHGioD9+PVf6qdtTBK"
|
invalidSignatureStr = "PZV6A2aI7n+MlyADqcqmWhkuyNrgUCDz+qSLSnI9bpasOwOhKUTx95m5Nu5CO/INa1LqzHGioD9+PVf6qdtTBK"
|
||||||
|
|
||||||
exampleDAGCBORFilename = "example.dagcbor"
|
|
||||||
exampleDAGJSONFilename = "example.dagjson"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed testdata/example.ipldsch
|
//go:embed testdata/example.ipldsch
|
||||||
var schemaBytes []byte
|
var schemaBytes []byte
|
||||||
|
|
||||||
|
//go:embed testdata/example.dagcbor
|
||||||
|
var exampleDagCbor []byte
|
||||||
|
|
||||||
|
//go:embed testdata/example.dagjson
|
||||||
|
var exampleDagJson []byte
|
||||||
|
|
||||||
var (
|
var (
|
||||||
once sync.Once
|
once sync.Once
|
||||||
ts *schema.TypeSystem
|
ts *schema.TypeSystem
|
||||||
@@ -59,7 +59,7 @@ func mustLoadSchema() *schema.TypeSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func exampleType() schema.Type {
|
func exampleType() schema.Type {
|
||||||
return mustLoadSchema().TypeByName(exampleTypeName)
|
return mustLoadSchema().TypeByName("Example")
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ envelope.Tokener = (*Example)(nil)
|
var _ envelope.Tokener = (*Example)(nil)
|
||||||
@@ -69,9 +69,7 @@ type Example struct {
|
|||||||
Issuer string
|
Issuer string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newExample(t *testing.T) *Example {
|
func newExample() *Example {
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
return &Example{
|
return &Example{
|
||||||
Hello: exampleGreeting,
|
Hello: exampleGreeting,
|
||||||
Issuer: exampleDID,
|
Issuer: exampleDID,
|
||||||
@@ -86,45 +84,30 @@ func (*Example) Tag() string {
|
|||||||
return exampleTag
|
return exampleTag
|
||||||
}
|
}
|
||||||
|
|
||||||
func exampleGoldenNode(t *testing.T) datamodel.Node {
|
func examplePrivKey(t *testing.T) crypto.PrivateKeySigningBytes {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
cbor := golden.Get(t, exampleDAGCBORFilename)
|
privBytes, err := base64.StdEncoding.DecodeString(examplePrivKeyB64)
|
||||||
|
|
||||||
node, err := ipld.Decode(cbor, dagcbor.Decode)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return node
|
privKey, err := ed25519.PrivateKeyFromBytes(privBytes)
|
||||||
}
|
|
||||||
|
|
||||||
func examplePrivKey(t *testing.T) crypto.PrivKey {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
privKeyEnc, err := crypto.ConfigDecodeKey(examplePrivKeyCfg)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
privKey, err := crypto.UnmarshalPrivateKey(privKeyEnc)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return privKey
|
return privKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func exampleSignature(t *testing.T) []byte {
|
// nodeWithInvalidSignature creates an IPLD node of a token, with an invalid signature
|
||||||
t.Helper()
|
func nodeWithInvalidSignature(t *testing.T) datamodel.Node {
|
||||||
|
|
||||||
sig, err := base64.RawStdEncoding.DecodeString(exampleSignatureStr)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
func invalidNodeFromGolden(t *testing.T) datamodel.Node {
|
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
invalidSig, err := base64.RawStdEncoding.DecodeString(invalidSignatureStr)
|
invalidSig, err := base64.RawStdEncoding.DecodeString(invalidSignatureStr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
envelNode := exampleGoldenNode(t)
|
cbor := exampleDagCbor
|
||||||
|
|
||||||
|
envelNode, err := ipld.Decode(cbor, dagcbor.Decode)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
sigPayloadNode, err := envelNode.LookupByIndex(1)
|
sigPayloadNode, err := envelNode.LookupByIndex(1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// a verified [TokenPayload].
|
// a verified [TokenPayload].
|
||||||
//
|
//
|
||||||
// Encoding functions in this package require a private key as a
|
// Encoding functions in this package require a private key as a
|
||||||
// parameter so the VarsigHeader can be set and so that a
|
// parameter so the VarsigBytes can be set and so that a
|
||||||
// cryptographic signature can be generated.
|
// cryptographic signature can be generated.
|
||||||
//
|
//
|
||||||
// Decoding functions in this package likewise perform the signature
|
// Decoding functions in this package likewise perform the signature
|
||||||
@@ -40,10 +40,10 @@ import (
|
|||||||
"github.com/ipld/go-ipld-prime/node/basicnode"
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
||||||
"github.com/ipld/go-ipld-prime/node/bindnode"
|
"github.com/ipld/go-ipld-prime/node/bindnode"
|
||||||
"github.com/ipld/go-ipld-prime/schema"
|
"github.com/ipld/go-ipld-prime/schema"
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
"github.com/ucan-wg/go-varsig"
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/did"
|
"code.sonr.org/go/did-it"
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/varsig"
|
"code.sonr.org/go/did-it/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -70,56 +70,56 @@ type Tokener interface {
|
|||||||
//
|
//
|
||||||
// An error is returned if the conversion fails, or if the resulting
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
// Tokener is invalid.
|
// Tokener is invalid.
|
||||||
func Decode[T Tokener](b []byte, decFn codec.Decoder) (T, error) {
|
func Decode[T Tokener](b []byte, decFn codec.Decoder, resolvOpts ...did.ResolutionOption) (T, error) {
|
||||||
node, err := ipld.Decode(b, decFn)
|
node, err := ipld.Decode(b, decFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return *new(T), err
|
return *new(T), err
|
||||||
}
|
}
|
||||||
|
|
||||||
return FromIPLD[T](node)
|
return FromIPLD[T](node, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeReader is the same as Decode, but accept an io.Reader.
|
// DecodeReader is the same as Decode, but accept an io.Reader.
|
||||||
func DecodeReader[T Tokener](r io.Reader, decFn codec.Decoder) (T, error) {
|
func DecodeReader[T Tokener](r io.Reader, decFn codec.Decoder, resolvOpts ...did.ResolutionOption) (T, error) {
|
||||||
node, err := ipld.DecodeStreaming(r, decFn)
|
node, err := ipld.DecodeStreaming(r, decFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return *new(T), err
|
return *new(T), err
|
||||||
}
|
}
|
||||||
|
|
||||||
return FromIPLD[T](node)
|
return FromIPLD[T](node, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromDagCbor unmarshals the input data into a Tokener.
|
// FromDagCbor unmarshals the input data into a Tokener.
|
||||||
//
|
//
|
||||||
// An error is returned if the conversion fails, or if the resulting
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
// Tokener is invalid.
|
// Tokener is invalid.
|
||||||
func FromDagCbor[T Tokener](b []byte) (T, error) {
|
func FromDagCbor[T Tokener](b []byte, resolvOpts ...did.ResolutionOption) (T, error) {
|
||||||
return Decode[T](b, dagcbor.Decode)
|
return Decode[T](b, dagcbor.Decode, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromDagCborReader is the same as FromDagCbor, but accept an io.Reader.
|
// FromDagCborReader is the same as FromDagCbor, but accept an io.Reader.
|
||||||
func FromDagCborReader[T Tokener](r io.Reader) (T, error) {
|
func FromDagCborReader[T Tokener](r io.Reader, resolvOpts ...did.ResolutionOption) (T, error) {
|
||||||
return DecodeReader[T](r, dagcbor.Decode)
|
return DecodeReader[T](r, dagcbor.Decode, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromDagJson unmarshals the input data into a Tokener.
|
// FromDagJson unmarshals the input data into a Tokener.
|
||||||
//
|
//
|
||||||
// An error is returned if the conversion fails, or if the resulting
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
// Tokener is invalid.
|
// Tokener is invalid.
|
||||||
func FromDagJson[T Tokener](b []byte) (T, error) {
|
func FromDagJson[T Tokener](b []byte, resolvOpts ...did.ResolutionOption) (T, error) {
|
||||||
return Decode[T](b, dagjson.Decode)
|
return Decode[T](b, dagjson.Decode, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromDagJsonReader is the same as FromDagJson, but accept an io.Reader.
|
// FromDagJsonReader is the same as FromDagJson, but accept an io.Reader.
|
||||||
func FromDagJsonReader[T Tokener](r io.Reader) (T, error) {
|
func FromDagJsonReader[T Tokener](r io.Reader, resolvOpts ...did.ResolutionOption) (T, error) {
|
||||||
return DecodeReader[T](r, dagjson.Decode)
|
return DecodeReader[T](r, dagjson.Decode, resolvOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromIPLD unwraps a Tokener from the provided IPLD datamodel.Node.
|
// FromIPLD unwraps a Tokener from the provided IPLD datamodel.Node.
|
||||||
//
|
//
|
||||||
// An error is returned if the conversion fails, or if the resulting
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
// Tokener is invalid.
|
// Tokener is invalid.
|
||||||
func FromIPLD[T Tokener](node datamodel.Node) (T, error) {
|
func FromIPLD[T Tokener](node datamodel.Node, resolvOpts ...did.ResolutionOption) (T, error) {
|
||||||
zero := *new(T)
|
zero := *new(T)
|
||||||
|
|
||||||
info, err := Inspect(node)
|
info, err := Inspect(node)
|
||||||
@@ -132,7 +132,7 @@ func FromIPLD[T Tokener](node datamodel.Node) (T, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This needs to be done before converting this node to its schema
|
// This needs to be done before converting this node to its schema
|
||||||
// representation (afterwards, the field might be renamed os it's safer
|
// representation (afterwards, the field might be renamed, so it's safer
|
||||||
// to use the wire name).
|
// to use the wire name).
|
||||||
issuerNode, err := info.tokenPayloadNode.LookupByString("iss")
|
issuerNode, err := info.tokenPayloadNode.LookupByString("iss")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -162,7 +162,7 @@ func FromIPLD[T Tokener](node datamodel.Node) (T, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check that the issuer's DID contains a public key with a type that
|
// Check that the issuer's DID contains a public key with a type that
|
||||||
// matches the VarsigHeader and then verify the SigPayload.
|
// matches the VarsigBytes and then verify the SigPayload.
|
||||||
issuer, err := issuerNode.AsString()
|
issuer, err := issuerNode.AsString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return zero, err
|
return zero, err
|
||||||
@@ -173,28 +173,35 @@ func FromIPLD[T Tokener](node datamodel.Node) (T, error) {
|
|||||||
return zero, err
|
return zero, err
|
||||||
}
|
}
|
||||||
|
|
||||||
issuerPubKey, err := issuerDID.PubKey()
|
issuerDoc, err := issuerDID.Document(resolvOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return zero, err
|
return zero, err
|
||||||
}
|
}
|
||||||
|
|
||||||
issuerVarsigHeader, err := varsig.Encode(issuerPubKey.Type())
|
vsig, err := varsig.Decode(info.VarsigBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return zero, err
|
return zero, fmt.Errorf("failed to decode varsig: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(info.VarsigHeader) != string(issuerVarsigHeader) {
|
var data []byte
|
||||||
return zero, errors.New("the VarsigHeader key type doesn't match the issuer's key type")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch vsig.PayloadEncoding() {
|
||||||
|
case varsig.PayloadEncodingDAGCBOR:
|
||||||
// TODO: can we use the already serialized CBOR data here, instead of encoding again the payload?
|
// TODO: can we use the already serialized CBOR data here, instead of encoding again the payload?
|
||||||
data, err := ipld.Encode(info.sigPayloadNode, dagcbor.Encode)
|
data, err = ipld.Encode(info.sigPayloadNode, dagcbor.Encode)
|
||||||
|
case varsig.PayloadEncodingDAGJSON:
|
||||||
|
data, err = ipld.Encode(info.sigPayloadNode, dagjson.Encode)
|
||||||
|
default:
|
||||||
|
return zero, errors.New("unsupported payload encoding")
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return zero, err
|
return zero, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err = issuerPubKey.Verify(data, info.Signature)
|
// TODO: use CapabilityDelegation() or CapabilityInvocation()
|
||||||
if err != nil || !ok {
|
|
||||||
|
ok, _ = did.TryAllVerifyBytes(issuerDoc.CapabilityDelegation(), data, info.Signature, crypto.WithVarsig(vsig))
|
||||||
|
if !ok {
|
||||||
return zero, errors.New("failed to verify the token's signature")
|
return zero, errors.New("failed to verify the token's signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +210,7 @@ func FromIPLD[T Tokener](node datamodel.Node) (T, error) {
|
|||||||
|
|
||||||
// Encode marshals a Tokener to the format specified by the provided
|
// Encode marshals a Tokener to the format specified by the provided
|
||||||
// codec.Encoder.
|
// codec.Encoder.
|
||||||
func Encode(privKey crypto.PrivKey, token Tokener, encFn codec.Encoder) ([]byte, error) {
|
func Encode(privKey crypto.PrivateKeySigningBytes, token Tokener, encFn codec.Encoder) ([]byte, error) {
|
||||||
node, err := ToIPLD(privKey, token)
|
node, err := ToIPLD(privKey, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -214,7 +221,7 @@ func Encode(privKey crypto.PrivKey, token Tokener, encFn codec.Encoder) ([]byte,
|
|||||||
|
|
||||||
// EncodeWriter is the same as Encode but outputs to an io.Writer instead
|
// EncodeWriter is the same as Encode but outputs to an io.Writer instead
|
||||||
// of encoding into a []byte.
|
// of encoding into a []byte.
|
||||||
func EncodeWriter(w io.Writer, privKey crypto.PrivKey, token Tokener, encFn codec.Encoder) error {
|
func EncodeWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes, token Tokener, encFn codec.Encoder) error {
|
||||||
node, err := ToIPLD(privKey, token)
|
node, err := ToIPLD(privKey, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -224,38 +231,36 @@ func EncodeWriter(w io.Writer, privKey crypto.PrivKey, token Tokener, encFn code
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToDagCbor marshals the Tokener to the DAG-CBOR format.
|
// ToDagCbor marshals the Tokener to the DAG-CBOR format.
|
||||||
func ToDagCbor(privKey crypto.PrivKey, token Tokener) ([]byte, error) {
|
func ToDagCbor(privKey crypto.PrivateKeySigningBytes, token Tokener) ([]byte, error) {
|
||||||
return Encode(privKey, token, dagcbor.Encode)
|
return Encode(privKey, token, dagcbor.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDagCborWriter is the same as ToDagCbor but outputs to an io.Writer
|
// ToDagCborWriter is the same as ToDagCbor but outputs to an io.Writer
|
||||||
// instead of encoding into a []byte.
|
// instead of encoding into a []byte.
|
||||||
func ToDagCborWriter(w io.Writer, privKey crypto.PrivKey, token Tokener) error {
|
func ToDagCborWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes, token Tokener) error {
|
||||||
return EncodeWriter(w, privKey, token, dagcbor.Encode)
|
return EncodeWriter(w, privKey, token, dagcbor.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDagJson marshals the Tokener to the DAG-JSON format.
|
// ToDagJson marshals the Tokener to the DAG-JSON format.
|
||||||
func ToDagJson(privKey crypto.PrivKey, token Tokener) ([]byte, error) {
|
func ToDagJson(privKey crypto.PrivateKeySigningBytes, token Tokener) ([]byte, error) {
|
||||||
return Encode(privKey, token, dagjson.Encode)
|
return Encode(privKey, token, dagjson.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDagJsonWriter is the same as ToDagJson but outputs to an io.Writer
|
// ToDagJsonWriter is the same as ToDagJson but outputs to an io.Writer
|
||||||
// instead of encoding into a []byte.
|
// instead of encoding into a []byte.
|
||||||
func ToDagJsonWriter(w io.Writer, privKey crypto.PrivKey, token Tokener) error {
|
func ToDagJsonWriter(w io.Writer, privKey crypto.PrivateKeySigningBytes, token Tokener) error {
|
||||||
return EncodeWriter(w, privKey, token, dagjson.Encode)
|
return EncodeWriter(w, privKey, token, dagjson.Encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToIPLD wraps the Tokener in an IPLD datamodel.Node.
|
// ToIPLD wraps the Tokener in an IPLD datamodel.Node.
|
||||||
func ToIPLD(privKey crypto.PrivKey, token Tokener) (datamodel.Node, error) {
|
func ToIPLD(privKey crypto.PrivateKeySigningBytes, token Tokener) (datamodel.Node, error) {
|
||||||
tokenPayloadNode := bindnode.Wrap(token, token.Prototype().Type()).Representation()
|
tokenPayloadNode := bindnode.Wrap(token, token.Prototype().Type()).Representation()
|
||||||
|
|
||||||
varsigHeader, err := varsig.Encode(privKey.Type())
|
opts := []crypto.SigningOption{crypto.WithPayloadEncoding(varsig.PayloadEncodingDAGCBOR)}
|
||||||
if err != nil {
|
vsig := privKey.Varsig(opts...)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sigPayloadNode, err := qp.BuildMap(basicnode.Prototype.Any, 2, func(ma datamodel.MapAssembler) {
|
sigPayloadNode, err := qp.BuildMap(basicnode.Prototype.Any, 2, func(ma datamodel.MapAssembler) {
|
||||||
qp.MapEntry(ma, VarsigHeaderKey, qp.Bytes(varsigHeader))
|
qp.MapEntry(ma, VarsigHeaderKey, qp.Bytes(vsig.Encode()))
|
||||||
qp.MapEntry(ma, token.Tag(), qp.Node(tokenPayloadNode))
|
qp.MapEntry(ma, token.Tag(), qp.Node(tokenPayloadNode))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -264,7 +269,7 @@ func ToIPLD(privKey crypto.PrivKey, token Tokener) (datamodel.Node, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
signature, err := privKey.Sign(data)
|
signature, err := privKey.SignToBytes(data, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -315,7 +320,7 @@ func FindTag(node datamodel.Node) (string, error) {
|
|||||||
type Info struct {
|
type Info struct {
|
||||||
Tag string
|
Tag string
|
||||||
Signature []byte
|
Signature []byte
|
||||||
VarsigHeader []byte
|
VarsigBytes []byte
|
||||||
sigPayloadNode datamodel.Node // private, we don't want to expose that
|
sigPayloadNode datamodel.Node // private, we don't want to expose that
|
||||||
tokenPayloadNode datamodel.Node // private, we don't want to expose that
|
tokenPayloadNode datamodel.Node // private, we don't want to expose that
|
||||||
}
|
}
|
||||||
@@ -367,7 +372,7 @@ func Inspect(node datamodel.Node) (Info, error) {
|
|||||||
switch {
|
switch {
|
||||||
case key == VarsigHeaderKey:
|
case key == VarsigHeaderKey:
|
||||||
foundVarsigHeader = true
|
foundVarsigHeader = true
|
||||||
res.VarsigHeader, err = v.AsBytes()
|
res.VarsigBytes, err = v.AsBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Info{}, err
|
return Info{}, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,18 @@ package envelope_test
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
_ "embed"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
_ "code.sonr.org/go/did-it/verifiers/did-key"
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gotest.tools/v3/golden"
|
|
||||||
|
|
||||||
"github.com/ucan-wg/go-ucan/token/internal/envelope"
|
"code.sonr.org/go/ucan/token/internal/envelope"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDecode(t *testing.T) {
|
func TestDecode(t *testing.T) {
|
||||||
@@ -22,9 +23,7 @@ func TestDecode(t *testing.T) {
|
|||||||
t.Run("via FromDagCbor", func(t *testing.T) {
|
t.Run("via FromDagCbor", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
data := golden.Get(t, "example.dagcbor")
|
tkn, err := envelope.FromDagCbor[*Example](exampleDagCbor)
|
||||||
|
|
||||||
tkn, err := envelope.FromDagCbor[*Example](data)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, exampleGreeting, tkn.Hello)
|
assert.Equal(t, exampleGreeting, tkn.Hello)
|
||||||
assert.Equal(t, exampleDID, tkn.Issuer)
|
assert.Equal(t, exampleDID, tkn.Issuer)
|
||||||
@@ -33,9 +32,7 @@ func TestDecode(t *testing.T) {
|
|||||||
t.Run("via FromDagJson", func(t *testing.T) {
|
t.Run("via FromDagJson", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
data := golden.Get(t, "example.dagjson")
|
tkn, err := envelope.FromDagJson[*Example](exampleDagJson)
|
||||||
|
|
||||||
tkn, err := envelope.FromDagJson[*Example](data)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, exampleGreeting, tkn.Hello)
|
assert.Equal(t, exampleGreeting, tkn.Hello)
|
||||||
assert.Equal(t, exampleDID, tkn.Issuer)
|
assert.Equal(t, exampleDID, tkn.Issuer)
|
||||||
@@ -48,17 +45,17 @@ func TestEncode(t *testing.T) {
|
|||||||
t.Run("via ToDagCbor", func(t *testing.T) {
|
t.Run("via ToDagCbor", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
data, err := envelope.ToDagCbor(examplePrivKey(t), newExample(t))
|
data, err := envelope.ToDagCbor(examplePrivKey(t), newExample())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
golden.AssertBytes(t, data, exampleDAGCBORFilename)
|
require.Equal(t, exampleDagCbor, data)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("via ToDagJson", func(t *testing.T) {
|
t.Run("via ToDagJson", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
data, err := envelope.ToDagJson(examplePrivKey(t), newExample(t))
|
data, err := envelope.ToDagJson(examplePrivKey(t), newExample())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
golden.Assert(t, string(data), exampleDAGJSONFilename)
|
require.Equal(t, exampleDagJson, data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,14 +65,14 @@ func TestRoundtrip(t *testing.T) {
|
|||||||
t.Run("via FromDagCbor/ToDagCbor", func(t *testing.T) {
|
t.Run("via FromDagCbor/ToDagCbor", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
dataIn := golden.Get(t, exampleDAGCBORFilename)
|
dataIn := exampleDagCbor
|
||||||
|
|
||||||
tkn, err := envelope.FromDagCbor[*Example](dataIn)
|
tkn, err := envelope.FromDagCbor[*Example](dataIn)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, exampleGreeting, tkn.Hello)
|
assert.Equal(t, exampleGreeting, tkn.Hello)
|
||||||
assert.Equal(t, exampleDID, tkn.Issuer)
|
assert.Equal(t, exampleDID, tkn.Issuer)
|
||||||
|
|
||||||
dataOut, err := envelope.ToDagCbor(examplePrivKey(t), newExample(t))
|
dataOut, err := envelope.ToDagCbor(examplePrivKey(t), newExample())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, dataIn, dataOut)
|
assert.Equal(t, dataIn, dataOut)
|
||||||
})
|
})
|
||||||
@@ -83,7 +80,7 @@ func TestRoundtrip(t *testing.T) {
|
|||||||
t.Run("via FromDagCborReader/ToDagCborWriter", func(t *testing.T) {
|
t.Run("via FromDagCborReader/ToDagCborWriter", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
data := golden.Get(t, exampleDAGCBORFilename)
|
data := exampleDagCbor
|
||||||
|
|
||||||
tkn, err := envelope.FromDagCborReader[*Example](bytes.NewReader(data))
|
tkn, err := envelope.FromDagCborReader[*Example](bytes.NewReader(data))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -91,21 +88,21 @@ func TestRoundtrip(t *testing.T) {
|
|||||||
assert.Equal(t, exampleDID, tkn.Issuer)
|
assert.Equal(t, exampleDID, tkn.Issuer)
|
||||||
|
|
||||||
w := &bytes.Buffer{}
|
w := &bytes.Buffer{}
|
||||||
require.NoError(t, envelope.ToDagCborWriter(w, examplePrivKey(t), newExample(t)))
|
require.NoError(t, envelope.ToDagCborWriter(w, examplePrivKey(t), newExample()))
|
||||||
assert.Equal(t, data, w.Bytes())
|
assert.Equal(t, data, w.Bytes())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("via FromDagJson/ToDagJson", func(t *testing.T) {
|
t.Run("via FromDagJson/ToDagJson", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
dataIn := golden.Get(t, exampleDAGJSONFilename)
|
dataIn := exampleDagJson
|
||||||
|
|
||||||
tkn, err := envelope.FromDagJson[*Example](dataIn)
|
tkn, err := envelope.FromDagJson[*Example](dataIn)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, exampleGreeting, tkn.Hello)
|
assert.Equal(t, exampleGreeting, tkn.Hello)
|
||||||
assert.Equal(t, exampleDID, tkn.Issuer)
|
assert.Equal(t, exampleDID, tkn.Issuer)
|
||||||
|
|
||||||
dataOut, err := envelope.ToDagJson(examplePrivKey(t), newExample(t))
|
dataOut, err := envelope.ToDagJson(examplePrivKey(t), newExample())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, dataIn, dataOut)
|
assert.Equal(t, dataIn, dataOut)
|
||||||
})
|
})
|
||||||
@@ -113,7 +110,7 @@ func TestRoundtrip(t *testing.T) {
|
|||||||
t.Run("via FromDagJsonReader/ToDagJsonrWriter", func(t *testing.T) {
|
t.Run("via FromDagJsonReader/ToDagJsonrWriter", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
data := golden.Get(t, exampleDAGJSONFilename)
|
data := exampleDagJson
|
||||||
|
|
||||||
tkn, err := envelope.FromDagJsonReader[*Example](bytes.NewReader(data))
|
tkn, err := envelope.FromDagJsonReader[*Example](bytes.NewReader(data))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -121,7 +118,7 @@ func TestRoundtrip(t *testing.T) {
|
|||||||
assert.Equal(t, exampleDID, tkn.Issuer)
|
assert.Equal(t, exampleDID, tkn.Issuer)
|
||||||
|
|
||||||
w := &bytes.Buffer{}
|
w := &bytes.Buffer{}
|
||||||
require.NoError(t, envelope.ToDagJsonWriter(w, examplePrivKey(t), newExample(t)))
|
require.NoError(t, envelope.ToDagJsonWriter(w, examplePrivKey(t), newExample()))
|
||||||
assert.Equal(t, data, w.Bytes())
|
assert.Equal(t, data, w.Bytes())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -129,7 +126,7 @@ func TestRoundtrip(t *testing.T) {
|
|||||||
func TestFromIPLD_with_invalid_signature(t *testing.T) {
|
func TestFromIPLD_with_invalid_signature(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
node := invalidNodeFromGolden(t)
|
node := nodeWithInvalidSignature(t)
|
||||||
tkn, err := envelope.FromIPLD[*Example](node)
|
tkn, err := envelope.FromIPLD[*Example](node)
|
||||||
assert.Nil(t, tkn)
|
assert.Nil(t, tkn)
|
||||||
require.EqualError(t, err, "failed to verify the token's signature")
|
require.EqualError(t, err, "failed to verify the token's signature")
|
||||||
@@ -158,18 +155,17 @@ func TestHash(t *testing.T) {
|
|||||||
func TestInspect(t *testing.T) {
|
func TestInspect(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
data := golden.Get(t, "example.dagcbor")
|
node, err := ipld.Decode(exampleDagCbor, dagcbor.Decode)
|
||||||
node, err := ipld.Decode(data, dagcbor.Decode)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expSig, err := base64.RawStdEncoding.DecodeString("fPqfwL3iFpbw9SvBiq0DIbUurv9o6c36R08tC/yslGrJcwV51ghzWahxdetpEf6T5LCszXX9I/K8khvnmAxjAg")
|
expSig, err := base64.RawStdEncoding.DecodeString("+xUwgl/5VZcTxx6iePmkrIaZAlxuelHTbeQ5lQIgIV3ZgHS+Jf5BUERB0fvmFfiIfa5A3yMPfEA/7rswYsRRCg")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
info, err := envelope.Inspect(node)
|
info, err := envelope.Inspect(node)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, expSig, info.Signature)
|
assert.Equal(t, expSig, info.Signature)
|
||||||
assert.Equal(t, "ucan/example@v1.0.0-rc.1", info.Tag)
|
assert.Equal(t, "ucan/example@v1.0.0-rc.1", info.Tag)
|
||||||
assert.Equal(t, []byte{0x34, 0xed, 0x1, 0x71}, info.VarsigHeader)
|
assert.Equal(t, []byte{0x34, 0x1, 0xed, 0x1, 0xed, 0x1, 0x13, 0x71}, info.VarsigBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FuzzInspect(f *testing.F) {
|
func FuzzInspect(f *testing.F) {
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
‚X@|úŸÀ½â–ðõ+ÁŠ!µ.®ÿhéÍúGO-ü¬”jÉsyÖsY¨quëiþ“ä°¬Íuý#ò¼’ç˜c¢ahD4íqxucan/example@v1.0.0-rc.1¢cissx8did:key:z6MkpuK2Amsu1RqcLGgmHHQHhvmeXCCBVsM4XFSg2cCyg4Nhehelloeworld
|
‚X@û0‚_ùU—Ç¢xù¤¬†™\nzQÓmä9• !]Ù€t¾%þAPDAÑûæøˆ}®@ß#|@?î»0bÄQ
|
||||||
|
¢ahH4ííqxucan/example@v1.0.0-rc.1¢cissx8did:key:z6MkuqvEtTW9L1E91CY3GmL83muetLAA2h8A5fUHjJgqq2Abehelloeworld
|
||||||
@@ -1 +1 @@
|
|||||||
[{"/":{"bytes":"fPqfwL3iFpbw9SvBiq0DIbUurv9o6c36R08tC/yslGrJcwV51ghzWahxdetpEf6T5LCszXX9I/K8khvnmAxjAg"}},{"h":{"/":{"bytes":"NO0BcQ"}},"ucan/example@v1.0.0-rc.1":{"hello":"world","iss":"did:key:z6MkpuK2Amsu1RqcLGgmHHQHhvmeXCCBVsM4XFSg2cCyg4Nh"}}]
|
[{"/":{"bytes":"+xUwgl/5VZcTxx6iePmkrIaZAlxuelHTbeQ5lQIgIV3ZgHS+Jf5BUERB0fvmFfiIfa5A3yMPfEA/7rswYsRRCg"}},{"h":{"/":{"bytes":"NAHtAe0BE3E"}},"ucan/example@v1.0.0-rc.1":{"hello":"world","iss":"did:key:z6MkuqvEtTW9L1E91CY3GmL83muetLAA2h8A5fUHjJgqq2Ab"}}]
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user