Source Code

;; genome-encryption - Clarity 4
;; Comprehensive encryption key management for genomic data

(define-constant ERR-KEY-NOT-FOUND (err u100))
(define-constant ERR-NOT-OWNER (err u101))
(define-constant ERR-KEY-EXPIRED (err u102))
(define-constant ERR-ALREADY-REVOKED (err u103))

(define-map encryption-keys uint
  {
    owner: principal,
    key-hash: (buff 64),
    algorithm: (string-ascii 20),
    key-version: uint,
    created-at: uint,
    expires-at: uint,
    is-revoked: bool
  }
)

(define-map key-access-grants { key-id: uint, grantee: principal }
  {
    access-level: (string-ascii 20),
    granted-at: uint,
    granted-by: principal,
    expires-at: uint,
    is-active: bool
  }
)

(define-map key-rotation-history uint
  {
    old-key-id: uint,
    new-key-id: uint,
    rotated-by: principal,
    rotated-at: uint,
    rotation-reason: (string-utf8 200)
  }
)

(define-map key-usage-logs uint
  {
    key-id: uint,
    used-by: principal,
    operation-type: (string-ascii 50),
    used-at: uint,
    success: bool
  }
)

(define-data-var key-counter uint u0)
(define-data-var rotation-counter uint u0)
(define-data-var usage-log-counter uint u0)
(define-data-var default-key-lifetime uint u5256000) ;; ~100 years in blocks

(define-public (register-key
    (key-hash (buff 64))
    (algorithm (string-ascii 20))
    (lifetime uint))
  (let ((key-id (+ (var-get key-counter) u1)))
    (map-set encryption-keys key-id
      {
        owner: tx-sender,
        key-hash: key-hash,
        algorithm: algorithm,
        key-version: u1,
        created-at: stacks-block-time,
        expires-at: (+ stacks-block-time lifetime),
        is-revoked: false
      })
    (var-set key-counter key-id)
    (ok key-id)))

(define-public (rotate-key
    (old-key-id uint)
    (new-key-hash (buff 64))
    (rotation-reason (string-utf8 200)))
  (let ((old-key (unwrap! (map-get? encryption-keys old-key-id) ERR-KEY-NOT-FOUND))
        (new-key-id (+ (var-get key-counter) u1))
        (rotation-id (+ (var-get rotation-counter) u1)))
    (asserts! (is-eq tx-sender (get owner old-key)) ERR-NOT-OWNER)
    (map-set encryption-keys new-key-id
      {
        owner: tx-sender,
        key-hash: new-key-hash,
        algorithm: (get algorithm old-key),
        key-version: (+ (get key-version old-key) u1),
        created-at: stacks-block-time,
        expires-at: (+ stacks-block-time (var-get default-key-lifetime)),
        is-revoked: false
      })
    (map-set key-rotation-history rotation-id
      {
        old-key-id: old-key-id,
        new-key-id: new-key-id,
        rotated-by: tx-sender,
        rotated-at: stacks-block-time,
        rotation-reason: rotation-reason
      })
    (var-set key-counter new-key-id)
    (var-set rotation-counter rotation-id)
    (ok new-key-id)))

(define-public (grant-key-access
    (key-id uint)
    (grantee principal)
    (access-level (string-ascii 20))
    (duration uint))
  (let ((key (unwrap! (map-get? encryption-keys key-id) ERR-KEY-NOT-FOUND)))
    (asserts! (is-eq tx-sender (get owner key)) ERR-NOT-OWNER)
    (asserts! (not (get is-revoked key)) ERR-ALREADY-REVOKED)
    (ok (map-set key-access-grants { key-id: key-id, grantee: grantee }
      {
        access-level: access-level,
        granted-at: stacks-block-time,
        granted-by: tx-sender,
        expires-at: (+ stacks-block-time duration),
        is-active: true
      }))))

(define-public (revoke-key-access
    (key-id uint)
    (grantee principal))
  (let ((key (unwrap! (map-get? encryption-keys key-id) ERR-KEY-NOT-FOUND))
        (grant (unwrap! (map-get? key-access-grants { key-id: key-id, grantee: grantee }) ERR-KEY-NOT-FOUND)))
    (asserts! (is-eq tx-sender (get owner key)) ERR-NOT-OWNER)
    (ok (map-set key-access-grants { key-id: key-id, grantee: grantee }
      (merge grant { is-active: false })))))

(define-public (revoke-key (key-id uint))
  (let ((key (unwrap! (map-get? encryption-keys key-id) ERR-KEY-NOT-FOUND)))
    (asserts! (is-eq tx-sender (get owner key)) ERR-NOT-OWNER)
    (asserts! (not (get is-revoked key)) ERR-ALREADY-REVOKED)
    (ok (map-set encryption-keys key-id
      (merge key { is-revoked: true })))))

(define-public (log-key-usage
    (key-id uint)
    (operation-type (string-ascii 50))
    (success bool))
  (let ((log-id (+ (var-get usage-log-counter) u1))
        (key (unwrap! (map-get? encryption-keys key-id) ERR-KEY-NOT-FOUND)))
    (map-set key-usage-logs log-id
      {
        key-id: key-id,
        used-by: tx-sender,
        operation-type: operation-type,
        used-at: stacks-block-time,
        success: success
      })
    (var-set usage-log-counter log-id)
    (ok log-id)))

(define-read-only (get-key-info (key-id uint))
  (ok (map-get? encryption-keys key-id)))

(define-read-only (get-key-access (key-id uint) (grantee principal))
  (ok (map-get? key-access-grants { key-id: key-id, grantee: grantee })))

(define-read-only (get-rotation-history (rotation-id uint))
  (ok (map-get? key-rotation-history rotation-id)))

(define-read-only (get-usage-log (log-id uint))
  (ok (map-get? key-usage-logs log-id)))

(define-read-only (is-key-valid (key-id uint))
  (match (map-get? encryption-keys key-id)
    key (ok (and
      (not (get is-revoked key))
      (< stacks-block-time (get expires-at key))))
    ERR-KEY-NOT-FOUND))

(define-read-only (validate-owner (owner principal))
  (principal-destruct? owner))

(define-read-only (format-key-id (key-id uint))
  (ok (int-to-ascii key-id)))

(define-read-only (parse-key-id (id-str (string-ascii 20)))
  (string-to-uint? id-str))

(define-read-only (get-bitcoin-block)
  (ok burn-block-height))

Functions (15)

FunctionAccessArgs
register-keypublickey-hash: (buff 64
rotate-keypublicold-key-id: uint, new-key-hash: (buff 64
grant-key-accesspublickey-id: uint, grantee: principal, access-level: (string-ascii 20
revoke-key-accesspublickey-id: uint, grantee: principal
revoke-keypublickey-id: uint
log-key-usagepublickey-id: uint, operation-type: (string-ascii 50
get-key-inforead-onlykey-id: uint
get-key-accessread-onlykey-id: uint, grantee: principal
get-rotation-historyread-onlyrotation-id: uint
get-usage-logread-onlylog-id: uint
is-key-validread-onlykey-id: uint
validate-ownerread-onlyowner: principal
format-key-idread-onlykey-id: uint
parse-key-idread-onlyid-str: (string-ascii 20
get-bitcoin-blockread-only