Smart Contract

Crypto

A.e467b9dd11fa00df.Crypto

Deployed

1w ago
Feb 19, 2026, 08:39:34 AM UTC

Dependents

0 imports
1
2access(all) contract Crypto {
3
4    access(all)
5    fun hash(_ data: [UInt8], algorithm: HashAlgorithm): [UInt8] {
6        return algorithm.hash(data)
7    }
8
9    access(all)
10    fun hashWithTag(_ data: [UInt8], tag: String, algorithm: HashAlgorithm): [UInt8] {
11        return algorithm.hashWithTag(data, tag: tag)
12    }
13
14    access(all)
15    struct KeyListEntry {
16
17        access(all)
18        let keyIndex: Int
19
20        access(all)
21        let publicKey: PublicKey
22
23        access(all)
24        let hashAlgorithm: HashAlgorithm
25
26        access(all)
27        let weight: UFix64
28
29        access(all)
30        let isRevoked: Bool
31
32        init(
33            keyIndex: Int,
34            publicKey: PublicKey,
35            hashAlgorithm: HashAlgorithm,
36            weight: UFix64,
37            isRevoked: Bool
38        ) {
39            self.keyIndex = keyIndex
40            self.publicKey = publicKey
41            self.hashAlgorithm = hashAlgorithm
42            self.weight = weight
43            self.isRevoked = isRevoked
44        }
45    }
46
47    access(all)
48    struct KeyList {
49
50        access(self)
51        let entries: [KeyListEntry]
52
53        init() {
54            self.entries = []
55        }
56
57        /// Adds a new key with the given weight
58        access(all)
59        fun add(
60            _ publicKey: PublicKey,
61            hashAlgorithm: HashAlgorithm,
62            weight: UFix64
63        ): KeyListEntry {
64
65            let keyIndex = self.entries.length
66            let entry = KeyListEntry(
67                keyIndex: keyIndex,
68                publicKey: publicKey,
69                hashAlgorithm: hashAlgorithm,
70                weight: weight,
71                isRevoked: false
72            )
73            self.entries.append(entry)
74            return entry
75        }
76
77        /// Returns the key at the given index, if it exists.
78        /// Revoked keys are always returned, but they have the `isRevoked` field set to true
79        access(all)
80        fun get(keyIndex: Int): KeyListEntry? {
81            if keyIndex >= self.entries.length {
82                return nil
83            }
84
85            return self.entries[keyIndex]
86        }
87
88        /// Marks the key at the given index revoked, but does not delete it
89        access(all)
90        fun revoke(keyIndex: Int) {
91            if keyIndex >= self.entries.length {
92                return
93            }
94
95            let currentEntry = self.entries[keyIndex]
96            self.entries[keyIndex] = KeyListEntry(
97                keyIndex: currentEntry.keyIndex,
98                publicKey: currentEntry.publicKey,
99                hashAlgorithm: currentEntry.hashAlgorithm,
100                weight: currentEntry.weight,
101                isRevoked: true
102            )
103        }
104
105        /// Returns true if the given signatures are valid for the given signed data
106        access(all)
107        fun verify(
108            signatureSet: [KeyListSignature],
109            signedData: [UInt8],
110            domainSeparationTag: String
111        ): Bool {
112
113            var validWeights: UFix64 = 0.0
114
115            let seenKeyIndices: {Int: Bool} = {}
116
117            for signature in signatureSet {
118
119                // Ensure the key index is valid
120                if signature.keyIndex >= self.entries.length {
121                    return false
122                }
123
124                // Ensure this key index has not already been seen
125                if seenKeyIndices[signature.keyIndex] ?? false {
126                    return false
127                }
128
129                // Record the key index was seen
130                seenKeyIndices[signature.keyIndex] = true
131
132                // Get the actual key
133                let key = self.entries[signature.keyIndex]
134
135                // Ensure the key is not revoked
136                if key.isRevoked {
137                    return false
138                }
139
140                // Ensure the signature is valid
141                if !key.publicKey.verify(
142                    signature: signature.signature,
143                    signedData: signedData,
144                    domainSeparationTag: domainSeparationTag,
145                    hashAlgorithm:key.hashAlgorithm
146                ) {
147                    return false
148                }
149
150                validWeights = validWeights + key.weight
151            }
152
153            return validWeights >= 1.0
154        }
155    }
156
157    access(all)
158    struct KeyListSignature {
159
160        access(all)
161        let keyIndex: Int
162
163        access(all)
164        let signature: [UInt8]
165
166        init(keyIndex: Int, signature: [UInt8]) {
167            self.keyIndex = keyIndex
168            self.signature = signature
169        }
170    }
171}