Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sining Data change, replace eip712 to eip191. #54

Merged
merged 2 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .changeset/hot-carrots-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
'@zcloak/did-resolver': minor
'@zcloak/crypto': minor
'@zcloak/verify': minor
'@zcloak/ctype': minor
'@zcloak/did': minor
'@zcloak/vc': minor
---

Sining Data change, replace eip712 to eip191.

- use eip191 to sign data when use `EcdsaSecp256k1VerificationKey2019` VerificationMethodType.
- upgrade vp version to `1`.
- verify functions support eip191 message.
- ctype, document add version field, default to set `0`.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"changeset": "zcloak-exec-changeset",
"clean": "zcloak-dev-clean-build",
"lint": "yarn lint:ts && yarn lint:dependencies",
"lint:ts": "zcloak-dev-run-lint",
"lint:dependencies": "zcloak-dev-lint-dependencies --fix",
"lint:ts": "zcloak-dev-run-lint",
"postinstall": "zcloak-dev-yarn-only",
"test": "zcloak-dev-run-test --coverage --forceExit --runInBand --testPathIgnorePatterns e2e",
"test:one": "zcloak-dev-run-test --runInBand",
Expand Down
25 changes: 25 additions & 0 deletions packages/crypto/src/eip191/eip191.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2021-2023 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { HexString } from '../types';

import { stringToU8a, u8aConcat, u8aToU8a } from '@polkadot/util';

import { keccak256AsU8a } from '../keccak';

/**
* @name eip191HashMessage
* @description
* keccak256 hash `message` with eip191 method, returns `Uint8Array`. See https://eips.ethereum.org/EIPS/eip-191
*/
export function eip191HashMessage(message: Uint8Array | HexString): Uint8Array {
const messageU8a = u8aToU8a(message);

return keccak256AsU8a(
u8aConcat(
stringToU8a('\x19Ethereum Signed Message:\n'),
stringToU8a(String(messageU8a.length)),
messageU8a
)
);
}
4 changes: 4 additions & 0 deletions packages/crypto/src/eip191/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright 2021-2023 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

export * from './eip191';
1 change: 1 addition & 0 deletions packages/crypto/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './blake2';
export * from './blake3';
export * from './blake3-2to1';
export * from './ed25519';
export * from './eip191';
export * from './eip712';
export * from './ethereum';
export * from './hdkey';
Expand Down
17 changes: 12 additions & 5 deletions packages/ctype/src/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
import type { HexString } from '@zcloak/crypto/types';
import type { Did } from '@zcloak/did';
import type { DidUrl } from '@zcloak/did-resolver/types';
import type { BaseCType, CType } from './types';
import type { BaseCType, CType, CTypeVersion } from './types';

import { u8aToHex } from '@polkadot/util';
import { numberToU8a, stringToU8a, u8aConcat, u8aToHex } from '@polkadot/util';

import { base58Encode, jsonCanonicalize, keccak256AsU8a } from '@zcloak/crypto';
import { parseDid } from '@zcloak/did-resolver/parseDid';

import { DEFAULT_CTYPE_SCHEMA } from './defaults';
import { getPublishCTypeTypedData } from './utils';

export function getCTypeHash(
base: BaseCType,
Expand All @@ -32,10 +31,17 @@ export function getCTypeHash(
return u8aToHex(keccak256AsU8a(jsonCanonicalize(obj)));
}

export function signedCTypeMessage(hash: HexString, version: CTypeVersion): Uint8Array {
return u8aConcat(stringToU8a('VersionedCtypeCreation'), numberToU8a(Number(version), 16), hash);
}

export async function getPublish(base: BaseCType, publisher: Did): Promise<CType> {
const hash = getCTypeHash(base, publisher.id);

const message = getPublishCTypeTypedData(hash);
const version: CTypeVersion = '0';

const message = signedCTypeMessage(hash, version);

const {
id,
signature,
Expand All @@ -48,6 +54,7 @@ export async function getPublish(base: BaseCType, publisher: Did): Promise<CType
...base,
publisher: id,
signature: base58Encode(signature),
signatureType
signatureType,
version
};
}
4 changes: 3 additions & 1 deletion packages/ctype/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import type { HexString } from '@zcloak/crypto/types';
import type { DidUrl, SignatureType } from '@zcloak/did-resolver/types';

export type CTypeVersion = '1';
export type CTypeVersion = '0';

export type InstanceType =
| 'object'
Expand Down Expand Up @@ -77,4 +77,6 @@ export interface CType extends BaseCType {
signature: string;
// since `@zcloak/ctype@1.0.0`
signatureType?: SignatureType;
// since `@zcloak/ctype@1.1.0`
version?: CTypeVersion;
}
24 changes: 0 additions & 24 deletions packages/ctype/src/utils.ts

This file was deleted.

6 changes: 5 additions & 1 deletion packages/did-resolver/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export type DidMethod = 'zk';

export type DidUrl = `did:${DidMethod}:${string}`;

export type DidDocumentVersion = '0';

export interface ParsedDid {
did: DidUrl;
didUrl: DidUrl;
Expand All @@ -22,7 +24,7 @@ export type VerificationMethodType =

export type SignatureType =
| 'EcdsaSecp256k1Signature2019'
| 'EcdsaSecp256k1SignatureEip712'
| 'EcdsaSecp256k1SignatureEip191'
| 'Ed25519Signature2018';

export interface VerificationMethod {
Expand All @@ -48,6 +50,8 @@ export interface DidDocumentProof {

export interface DidDocument {
'@context': ['https://www.w3.org/ns/did/v1'];
// since `@zcloak/did-resolver@1.1.0`
version?: DidDocumentVersion;
id: DidUrl;
controller: DidUrl[];
verificationMethod?: VerificationMethod[];
Expand Down
10 changes: 6 additions & 4 deletions packages/did/src/did/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { assert } from '@polkadot/util';

import { base58Encode } from '@zcloak/crypto';

import { getPublishDocumentTypedData } from '../utils';
import { hashDidDocument, signedDidDocumentMessage } from '../hasher';
import { DidKeyring } from './keyring';

export abstract class DidChain extends DidKeyring {
Expand All @@ -22,6 +22,7 @@ export abstract class DidChain extends DidKeyring {

const document: DidDocument = {
'@context': ['https://www.w3.org/ns/did/v1'],
version: '0',
id: this.id,
controller: [...this.controller]
};
Expand Down Expand Up @@ -80,11 +81,11 @@ export abstract class DidChain extends DidKeyring {
public async getPublish(): Promise<DidDocumentWithProof> {
const document = this.getDocument();

document.creationTime = Date.now();

const proof: DidDocumentProof[] = document.proof ?? [];

const message = getPublishDocumentTypedData(document);
assert(document.version, 'Must have version field when publish');

const message = signedDidDocumentMessage(hashDidDocument(document), document.version);

const {
id,
Expand All @@ -96,6 +97,7 @@ export abstract class DidChain extends DidKeyring {

return {
...document,
creationTime: Date.now(),
proof
};
}
Expand Down
74 changes: 10 additions & 64 deletions packages/did/src/did/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import { alice, bob, DOCUMENTS, testResolver } from 'test-support';

import {
decodeMultibase,
eip712,
eip191HashMessage,
ethereumEncode,
initCrypto,
keccak256AsU8a,
secp256k1Verify
} from '@zcloak/crypto';
import { TypedData } from '@zcloak/crypto/eip712/types';
import { Keyring } from '@zcloak/keyring';

import { getPublishDocumentTypedData } from '../utils';
import { hashDidDocument, signedDidDocumentMessage } from '../hasher';
import { createEcdsaFromMnemonic } from './helpers';

describe('Did', (): void => {
Expand Down Expand Up @@ -85,87 +83,33 @@ describe('Did', (): void => {

expect(
secp256k1Verify(
keccak256AsU8a(message),
eip191HashMessage(message),
signature1.signature,
bob.get(bob.getKeyUrl('authentication')).publicKey
)
).toBe(true);
expect(
secp256k1Verify(
keccak256AsU8a(message),
eip191HashMessage(message),
signature2.signature,
bob.get(bob.getKeyUrl('assertionMethod')).publicKey
)
).toBe(true);
expect(
secp256k1Verify(
keccak256AsU8a(message),
eip191HashMessage(message),
signature3.signature,
bob.get(bob.getKeyUrl('capabilityDelegation')).publicKey
)
).toBe(true);
expect(
secp256k1Verify(
keccak256AsU8a(message),
eip191HashMessage(message),
signature4.signature,
bob.get(bob.getKeyUrl('capabilityInvocation')).publicKey
)
).toBe(true);
});

it('sign a TypedData', async (): Promise<void> => {
const typedData: TypedData = {
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' }
],
Test: [{ name: 'test', type: 'bytes' }]
},
primaryType: 'Test',
domain: {
name: 'Test',
version: '0'
},
message: {
test: '0x1234'
}
};

const signature1 = await alice.signWithKey(typedData, 'authentication');
const signature2 = await alice.signWithKey(typedData, 'assertionMethod');
const signature3 = await alice.signWithKey(typedData, 'capabilityDelegation');
const signature4 = await alice.signWithKey(typedData, 'capabilityInvocation');

expect(
secp256k1Verify(
eip712.getMessage(typedData, true),
signature1.signature,
alice.get(alice.getKeyUrl('authentication')).publicKey
)
).toBe(true);
expect(
secp256k1Verify(
eip712.getMessage(typedData, true),
signature2.signature,
alice.get(alice.getKeyUrl('assertionMethod')).publicKey
)
).toBe(true);
expect(
secp256k1Verify(
eip712.getMessage(typedData, true),
signature3.signature,
alice.get(alice.getKeyUrl('capabilityDelegation')).publicKey
)
).toBe(true);
expect(
secp256k1Verify(
eip712.getMessage(typedData, true),
signature4.signature,
alice.get(alice.getKeyUrl('capabilityInvocation')).publicKey
)
).toBe(true);
});
});

describe('encrypt and decrypt', (): void => {
Expand Down Expand Up @@ -193,11 +137,13 @@ describe('Did', (): void => {
it('getPublish verify', async (): Promise<void> => {
const document = await alice.getPublish();

expect(document.proof[0].signatureType).toBe('EcdsaSecp256k1SignatureEip712');
expect(document.proof[0].signatureType).toBe('EcdsaSecp256k1SignatureEip191');

expect(
secp256k1Verify(
eip712.getMessage(getPublishDocumentTypedData(document), true),
eip191HashMessage(
signedDidDocumentMessage(hashDidDocument(document), document.version || '0')
),
decodeMultibase(document.proof[0].signature),
alice.get(alice.getKeyUrl('capabilityInvocation')).publicKey
)
Expand Down
2 changes: 1 addition & 1 deletion packages/did/src/did/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Did extends DidChain {

const document = this.getDocument();

return u8aEq(hashDidDocument(onChainDocument, false), hashDidDocument(document, false));
return u8aEq(hashDidDocument(onChainDocument), hashDidDocument(document));
}

public addService(service: Service): void {
Expand Down
Loading