pub struct Claim {
pub data: String,
pub metadata: Option<String>,
pub timestamp: u64,
}Expand description
A Claim representing a statement of truth to be anchored. Fields are ordered alphabetically to ensure “Canonical JSON” (JCS - RFC 8785) compliance when using deterministic serialization.
Fields§
§data: StringThe actual data being claimed (e.g., “AI Model v1.0 Accuracy: 98%”)
metadata: Option<String>Optional metadata or context
timestamp: u64Timestamp of the claim (UTC seconds)
Implementations§
Source§impl Claim
impl Claim
Sourcepub fn new(data: String) -> Self
pub fn new(data: String) -> Self
Create a new claim with the current system time (requires “std”)
Sourcepub fn new_with_timestamp(data: String, timestamp: u64) -> Result<Self>
pub fn new_with_timestamp(data: String, timestamp: u64) -> Result<Self>
Create a new claim with a provided timestamp (useful for no-std)
Examples found in repository?
examples/generate_test_vectors.rs (line 14)
9fn main() {
10 println!("Generating cross-SDK test vectors...\n");
11
12 // Test Vector 1: Basic claim
13 let keypair1 = generate_keypair();
14 let claim1 = Claim::new_with_timestamp("test_data_123".to_string(), 1704067200).unwrap();
15 let signed1 = sign_claim(&claim1, &keypair1).unwrap();
16
17 let vector1 = json!({
18 "name": "basic_claim",
19 "description": "Basic claim with data and timestamp",
20 "public_key": hex::encode(keypair1.verifying_key().as_bytes()),
21 "claim": {
22 "data": claim1.data,
23 "timestamp": claim1.timestamp,
24 },
25 "canonical_json": r#"{"data":"test_data_123","timestamp":1704067200}"#,
26 "expected_signature": signed1.signature,
27 });
28
29 // Test Vector 2: Claim with metadata
30 let keypair2 = generate_keypair();
31 let mut claim2 = Claim::new_with_timestamp("hash_abc123".to_string(), 1704067200).unwrap();
32 claim2.metadata = Some("user_id:12345".to_string());
33 let signed2 = sign_claim(&claim2, &keypair2).unwrap();
34
35 let vector2 = json!({
36 "name": "claim_with_metadata",
37 "description": "Claim with optional metadata field",
38 "private_key": hex::encode(keypair2.to_bytes()),
39 "public_key": hex::encode(keypair2.verifying_key().as_bytes()),
40 "claim": {
41 "data": claim2.data,
42 "metadata": claim2.metadata,
43 "timestamp": claim2.timestamp,
44 },
45 "canonical_json": r#"{"data":"hash_abc123","metadata":"user_id:12345","timestamp":1704067200}"#,
46 "expected_signature": signed2.signature,
47 });
48
49 // Test Vector 3: Hash computation
50 let hash1 = compute_hash(b"hello");
51 let hash2 = compute_hash(b"");
52 let hash3 = compute_hash(b"Provncloud SDK");
53
54 let vector3 = json!({
55 "name": "hash_computation",
56 "description": "SHA-256 hash test vectors",
57 "test_cases": [
58 {
59 "input": "hello",
60 "expected_hash": hash1
61 },
62 {
63 "input": "",
64 "expected_hash": hash2
65 },
66 {
67 "input": "Provncloud SDK",
68 "expected_hash": hash3
69 }
70 ]
71 });
72
73 // Test Vector 4: Cross-sign test (same claim, different keys)
74 let keypair_a = generate_keypair();
75 let keypair_b = generate_keypair();
76 let claim_cross = Claim::new_with_timestamp("cross_test_data".to_string(), 1704067200).unwrap();
77
78 let signed_by_a = sign_claim(&claim_cross, &keypair_a).unwrap();
79 let signed_by_b = sign_claim(&claim_cross, &keypair_b).unwrap();
80
81 let vector4 = json!({
82 "name": "cross_sign_same_claim",
83 "description": "Same claim signed by two different keys",
84 "claim": {
85 "data": claim_cross.data,
86 "timestamp": claim_cross.timestamp,
87 },
88 "canonical_json": r#"{"data":"cross_test_data","timestamp":1704067200}"#,
89 "signatures": [
90 {
91 "signer": "key_a",
92 "private_key": hex::encode(keypair_a.to_bytes()),
93 "public_key": hex::encode(keypair_a.verifying_key().as_bytes()),
94 "signature": signed_by_a.signature
95 },
96 {
97 "signer": "key_b",
98 "private_key": hex::encode(keypair_b.to_bytes()),
99 "public_key": hex::encode(keypair_b.verifying_key().as_bytes()),
100 "signature": signed_by_b.signature
101 }
102 ]
103 });
104
105 // Combine all vectors
106 let test_vectors = json!({
107 "spec_version": "1.0",
108 "sdk_version": "0.2.0",
109 "generated_at": "2024-01-01T00:00:00Z",
110 "test_vectors": [
111 vector1,
112 vector2,
113 vector3,
114 vector4
115 ]
116 });
117
118 // Print as formatted JSON
119 println!("{}", serde_json::to_string_pretty(&test_vectors).unwrap());
120}Sourcepub fn to_signable_bytes(&self) -> Result<Vec<u8>>
pub fn to_signable_bytes(&self) -> Result<Vec<u8>>
Canonical serialization for signing (Sorted keys, no whitespace) This follows JCS (RFC 8785) logic by relying on struct field ordering.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Claim
impl<'de> Deserialize<'de> for Claim
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
impl Eq for Claim
impl StructuralPartialEq for Claim
Auto Trait Implementations§
impl Freeze for Claim
impl RefUnwindSafe for Claim
impl Send for Claim
impl Sync for Claim
impl Unpin for Claim
impl UnsafeUnpin for Claim
impl UnwindSafe for Claim
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more