Skip to content

Commit eda9be9

Browse files
committed
another security pass
1 parent 246db46 commit eda9be9

File tree

6 files changed

+358
-0
lines changed

6 files changed

+358
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ adheres to the format set out by [Keep a Changelog](https://keepachangelog.com/e
121121
- Enhanced main package docs with examples
122122
- Updated README with feature highlights and usage examples
123123
- Improved godoc comments for all public APIs
124+
- Added doc.go files for all internal packages (bcs, crypto, http, types, util)
125+
- Internal crypto package documents all key types, authentication schemes, and security considerations
126+
- Internal BCS package documents serialization patterns and performance optimizations
127+
- Internal HTTP package documents middleware composition patterns
124128

125129
# v1.11.0 (9/26/2025)
126130

v2/internal/bcs/doc.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Package bcs implements Binary Canonical Serialization (BCS) for Aptos.
2+
//
3+
// BCS is the serialization format used by the Aptos blockchain for all on-chain data.
4+
// It is a deterministic, non-self-describing binary format that provides:
5+
// - Canonical encoding (same data always produces same bytes)
6+
// - Compact representation
7+
// - Fast serialization/deserialization
8+
//
9+
// # Interface-based Serialization
10+
//
11+
// For fine-grained control, implement the Marshaler and Unmarshaler interfaces:
12+
//
13+
// type MyStruct struct {
14+
// Value uint64
15+
// Name string
16+
// }
17+
//
18+
// func (s *MyStruct) MarshalBCS(ser *Serializer) {
19+
// ser.U64(s.Value)
20+
// ser.WriteString(s.Name)
21+
// }
22+
//
23+
// func (s *MyStruct) UnmarshalBCS(des *Deserializer) {
24+
// s.Value = des.U64()
25+
// s.Name = des.ReadString()
26+
// }
27+
//
28+
// // Serialize
29+
// data, err := bcs.Serialize(&myStruct)
30+
//
31+
// // Deserialize
32+
// var result MyStruct
33+
// err := bcs.Deserialize(&result, data)
34+
//
35+
// # Reflection-based Serialization
36+
//
37+
// For convenience, use struct tags with Marshal/Unmarshal:
38+
//
39+
// type MyStruct struct {
40+
// Value uint64 `bcs:"1"`
41+
// Name string `bcs:"2"`
42+
// }
43+
//
44+
// data, err := bcs.Marshal(&myStruct)
45+
// err := bcs.Unmarshal(data, &result)
46+
//
47+
// # Supported Types
48+
//
49+
// Primitives:
50+
// - bool, uint8, uint16, uint32, uint64, int8, int16, int32, int64
51+
// - *big.Int for U128/U256/I128/I256
52+
// - string (UTF-8 with length prefix)
53+
// - []byte (with length prefix)
54+
//
55+
// Composite types:
56+
// - Structs (fields serialized in order)
57+
// - Slices (length prefix + elements)
58+
// - Maps (length prefix + key-value pairs, sorted by key)
59+
// - Pointers (Option type: 0 for nil, 1 + value for non-nil)
60+
//
61+
// # Thread Safety
62+
//
63+
// Serializer and Deserializer are NOT thread-safe. Each goroutine should
64+
// use its own instance. The Serialize/Deserialize functions handle this
65+
// automatically using sync.Pool.
66+
//
67+
// # Performance
68+
//
69+
// The package uses several optimizations:
70+
// - sync.Pool for Serializer reuse
71+
// - Stack-allocated buffers for small integers
72+
// - Zeroing of pooled buffers to prevent data leakage
73+
package bcs

v2/internal/crypto/doc.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Package crypto provides cryptographic primitives for the Aptos blockchain.
2+
//
3+
// This internal package implements all cryptographic operations required by the SDK:
4+
// - Key generation and management
5+
// - Digital signatures
6+
// - Authentication key derivation
7+
// - BCS serialization of cryptographic types
8+
//
9+
// # Supported Key Types
10+
//
11+
// Ed25519:
12+
// - Ed25519PrivateKey: Standard Ed25519 signing key
13+
// - Ed25519PublicKey: Ed25519 verification key
14+
// - Ed25519Signature: 64-byte Ed25519 signature
15+
//
16+
// Secp256k1:
17+
// - Secp256k1PrivateKey: ECDSA signing key (Bitcoin-style)
18+
// - Secp256k1PublicKey: Uncompressed public key (65 bytes)
19+
// - Secp256k1Signature: ECDSA signature (r || s, 64 bytes)
20+
//
21+
// Secp256r1 (P-256):
22+
// - Secp256r1PrivateKey: ECDSA signing key (WebAuthn-compatible)
23+
// - Secp256r1PublicKey: Uncompressed public key (65 bytes)
24+
// - Secp256r1Signature: ECDSA signature (r || s, 64 bytes)
25+
//
26+
// Post-Quantum:
27+
// - SlhDsaPrivateKey: SPHINCS+ SLH-DSA-SHA2-128s signing key
28+
// - SlhDsaPublicKey: SLH-DSA public key (32 bytes)
29+
// - SlhDsaSignature: SLH-DSA signature (7856 bytes)
30+
//
31+
// # Authentication Schemes
32+
//
33+
// SingleKey (scheme 0x02):
34+
// - AnyPublicKey wraps any supported key type
35+
// - AnySignature wraps the corresponding signature type
36+
// - Used for modern single-signer accounts
37+
//
38+
// MultiKey (scheme 0x03):
39+
// - Combines multiple AnyPublicKey instances
40+
// - K-of-N threshold signatures
41+
// - Supports heterogeneous key types
42+
//
43+
// Legacy schemes:
44+
// - Ed25519Scheme (0x00): Legacy Ed25519 accounts
45+
// - MultiEd25519Scheme (0x01): Legacy multi-sig Ed25519
46+
//
47+
// # WebAuthn Support
48+
//
49+
// The package supports WebAuthn/Passkey authentication:
50+
// - PartialAuthenticatorAssertionResponse: WebAuthn assertion
51+
// - AssertionSignature: Wraps Secp256r1 signature
52+
// - Verification of client data and authenticator data
53+
//
54+
// # Keyless Authentication
55+
//
56+
// Types for OIDC-based keyless accounts:
57+
// - KeylessPublicKey: OIDC identity commitment
58+
// - FederatedKeylessPublicKey: With JWK address
59+
// - KeylessSignature: ZK proof or OpenID signature
60+
//
61+
// # Thread Safety
62+
//
63+
// Private key types (Ed25519PrivateKey, Secp256k1PrivateKey, Secp256r1PrivateKey)
64+
// are thread-safe. Cached public keys and authentication keys are protected by
65+
// sync.RWMutex using double-checked locking.
66+
//
67+
// Public key and signature types are immutable after creation and safe to share.
68+
//
69+
// # Security Considerations
70+
//
71+
// - Private keys are redacted in String() methods to prevent accidental logging
72+
// - Signature malleability is prevented by enforcing low-s values
73+
// - WebAuthn uses constant-time comparison for challenge verification
74+
// - All pooled resources clear sensitive data before reuse
75+
package crypto

v2/internal/http/doc.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Package http provides HTTP client utilities for the Aptos SDK.
2+
//
3+
// This internal package provides composable HTTP client middleware:
4+
// - Retry with exponential backoff
5+
// - Rate limiting
6+
// - Request/response logging
7+
// - Custom header injection
8+
// - Timeout management
9+
//
10+
// # HTTPDoer Interface
11+
//
12+
// All middleware implements the HTTPDoer interface:
13+
//
14+
// type HTTPDoer interface {
15+
// Do(req *http.Request) (*http.Response, error)
16+
// }
17+
//
18+
// This allows composing multiple middleware layers:
19+
//
20+
// base := &http.Client{}
21+
// withTimeout := NewTimeoutClient(base, 30*time.Second)
22+
// withRetry := NewRetryClient(withTimeout, DefaultRetryConfig(), logger)
23+
// withLogging := NewLoggingClient(withRetry, logger)
24+
//
25+
// # Retry Client
26+
//
27+
// RetryClient provides automatic retry with exponential backoff:
28+
//
29+
// client := NewRetryClient(inner, RetryConfig{
30+
// MaxRetries: 3,
31+
// InitialBackoff: 100 * time.Millisecond,
32+
// MaxBackoff: 10 * time.Second,
33+
// Multiplier: 2.0,
34+
// Jitter: 0.1,
35+
// RetryableStatusCodes: []int{429, 500, 502, 503, 504},
36+
// }, logger)
37+
//
38+
// Features:
39+
// - Respects Retry-After headers
40+
// - Configurable status codes to retry
41+
// - Jitter to prevent thundering herd
42+
// - Context cancellation support
43+
//
44+
// # Rate Limiter
45+
//
46+
// RateLimitedClient implements token bucket rate limiting:
47+
//
48+
// client := NewRateLimitedClient(inner, 10.0, 20, logger) // 10 req/s, burst 20
49+
//
50+
// # Header Client
51+
//
52+
// HeaderClient adds custom headers to all requests:
53+
//
54+
// client := NewHeaderClient(inner, map[string]string{
55+
// "Authorization": "Bearer token",
56+
// "X-Custom": "value",
57+
// })
58+
//
59+
// # Timeout Client
60+
//
61+
// TimeoutClient applies a default timeout to requests without one:
62+
//
63+
// client := NewTimeoutClient(inner, 30*time.Second)
64+
//
65+
// # Logging Client
66+
//
67+
// LoggingClient logs request/response details using slog:
68+
//
69+
// client := NewLoggingClient(inner, slog.Default())
70+
package http

v2/internal/types/doc.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Package types provides core type definitions for the Aptos Go SDK.
2+
//
3+
// This internal package defines fundamental types used throughout the SDK:
4+
// - AccountAddress: 32-byte blockchain addresses
5+
// - TypeTag: Move type system representation
6+
//
7+
// # AccountAddress
8+
//
9+
// AccountAddress represents a 32-byte address on the Aptos blockchain:
10+
//
11+
// // Parse from string
12+
// addr, err := types.ParseAddress("0x1")
13+
// addr, err := types.ParseAddress("0x0000000000000000000000000000000000000000000000000000000000000001")
14+
//
15+
// // Must-parse (panics on error, useful for constants)
16+
// addr := types.MustParseAddress("0x1")
17+
//
18+
// // String representation
19+
// str := addr.String() // "0x1" for special addresses, full hex otherwise
20+
// str := addr.StringLong() // Always full 64-char hex
21+
// str := addr.StringShort() // Minimal hex without leading zeros
22+
//
23+
// Special addresses (0x0 through 0xf) use short-form representation per AIP-40.
24+
//
25+
// # TypeTag
26+
//
27+
// TypeTag represents Move types for generic functions:
28+
//
29+
// // Parse from string
30+
// tag, err := types.ParseTypeTag("0x1::aptos_coin::AptosCoin")
31+
// tag, err := types.ParseTypeTag("vector<u8>")
32+
// tag, err := types.ParseTypeTag("0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>")
33+
//
34+
// // Primitive types
35+
// tag := types.TypeTagBool
36+
// tag := types.TypeTagU64
37+
// tag := types.TypeTagAddress
38+
//
39+
// # BCS Serialization
40+
//
41+
// All types implement BCS serialization:
42+
//
43+
// // AccountAddress serializes as 32 fixed bytes
44+
// data, err := bcs.Serialize(&addr)
45+
//
46+
// // TypeTag serializes with variant prefix
47+
// data, err := bcs.Serialize(&tag)
48+
//
49+
// # JSON Serialization
50+
//
51+
// Types support JSON for API interactions:
52+
//
53+
// // AccountAddress marshals to quoted hex string
54+
// data, _ := json.Marshal(addr) // "\"0x1\""
55+
//
56+
// // TypeTag marshals to string representation
57+
// data, _ := json.Marshal(tag) // "\"0x1::aptos_coin::AptosCoin\""
58+
//
59+
// # Thread Safety
60+
//
61+
// AccountAddress and TypeTag are immutable value types and safe to use
62+
// concurrently after creation.
63+
//
64+
// # Performance
65+
//
66+
// Address operations are optimized:
67+
// - ParseAddress avoids allocations for odd-length hex
68+
// - String() uses pre-computed table for special addresses (0x0-0xf)
69+
package types

v2/internal/util/doc.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Package util provides internal helper functions for the Aptos Go SDK.
2+
//
3+
// This internal package contains utility functions used throughout the SDK:
4+
// - Hash functions
5+
// - Hex encoding/decoding
6+
// - Type conversions
7+
// - Buffer pooling
8+
//
9+
// # Hash Functions
10+
//
11+
// SHA3-256 hashing with pooled hashers for performance:
12+
//
13+
// hash := util.Sha3256Hash([][]byte{data1, data2})
14+
//
15+
// The hasher pool reduces allocations in hot paths like signature verification
16+
// and authentication key derivation.
17+
//
18+
// # Hex Encoding
19+
//
20+
// Convert between bytes and hex strings:
21+
//
22+
// // Encode with 0x prefix
23+
// hex := util.BytesToHex(bytes) // "0x..."
24+
//
25+
// // Decode with optional 0x prefix
26+
// bytes, err := util.ParseHex("0x1234")
27+
// bytes, err := util.ParseHex("1234")
28+
//
29+
// BytesToHex is optimized to avoid intermediate allocations.
30+
//
31+
// # Type Conversions
32+
//
33+
// Safe integer conversions with bounds checking:
34+
//
35+
// u8, err := util.IntToU8(255) // OK
36+
// u8, err := util.IntToU8(256) // Error: out of range
37+
//
38+
// u16, err := util.IntToU16(value)
39+
// u32, err := util.IntToU32(value)
40+
// u8, err := util.Uint32ToU8(value)
41+
//
42+
// String to number conversions:
43+
//
44+
// n, err := util.StrToUint64("123")
45+
// bigInt, err := util.StrToBigInt("123456789012345678901234567890")
46+
//
47+
// # Buffer Pools
48+
//
49+
// Reusable byte buffers for common sizes:
50+
//
51+
// buf := util.GetBuffer32()
52+
// defer util.PutBuffer32(buf)
53+
// // Use (*buf)[:] for operations
54+
//
55+
// buf := util.GetBuffer64()
56+
// defer util.PutBuffer64(buf)
57+
//
58+
// Buffer pools:
59+
// - Clear sensitive data before returning to pool
60+
// - Validate both length AND capacity on return
61+
// - Reject modified buffers to prevent data leakage
62+
//
63+
// # Thread Safety
64+
//
65+
// All functions in this package are thread-safe. Pooled resources use
66+
// sync.Pool which handles concurrent access.
67+
package util

0 commit comments

Comments
 (0)